diff options
author | Olivier Lamy <olamy@apache.org> | 2012-12-27 14:55:12 +0000 |
---|---|---|
committer | Olivier Lamy <olamy@apache.org> | 2012-12-27 14:55:12 +0000 |
commit | 708a34f1f23b9c1a20abb244fecd299992480a4b (patch) | |
tree | d54069226f6ee121e308a55bfcc0bd4401a8f8f1 /archiva-modules/archiva-web/archiva-webapp/src | |
parent | 58edbc0c438c92c593780f355eae3505e36037e3 (diff) | |
download | archiva-708a34f1f23b9c1a20abb244fecd299992480a4b.tar.gz archiva-708a34f1f23b9c1a20abb244fecd299992480a4b.zip |
rename archiva-webapp-js module to archiva-webapp
git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1426213 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'archiva-modules/archiva-web/archiva-webapp/src')
155 files changed, 38073 insertions, 0 deletions
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/resources/META-INF/spring-context.xml b/archiva-modules/archiva-web/archiva-webapp/src/main/resources/META-INF/spring-context.xml new file mode 100755 index 000000000..a948d74aa --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/resources/META-INF/spring-context.xml @@ -0,0 +1,51 @@ +<?xml version="1.0"?> + +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the License is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + ~ KIND, either express or implied. See the License for the + ~ specific language governing permissions and limitations + ~ under the License. + --> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:context="http://www.springframework.org/schema/context" + xmlns:util="http://www.springframework.org/schema/util" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-3.0.xsd + http://www.springframework.org/schema/context + http://www.springframework.org/schema/context/spring-context-3.0.xsd + http://www.springframework.org/schema/util + http://www.springframework.org/schema/util/spring-util-3.0.xsd" + default-lazy-init="true"> + + <context:annotation-config/> + <context:component-scan base-package="org.apache.archiva.web.api"/> + + + <util:properties id="archivaRuntimeProperties" location="classpath:application.properties" /> + + <bean id="jcr-repository" class="org.apache.jackrabbit.core.RepositoryImpl" destroy-method="shutdown" lazy-init="true"> + <constructor-arg ref="jcr-config"/> + </bean> + + <bean id="jcr-config" class="org.apache.archiva.metadata.repository.jcr.ArchivaJcrRepositoryConfig" factory-method="create"> + <constructor-arg value="${appserver.base}/conf/repository.xml"/> + <constructor-arg value="${appserver.base}/data/jcr"/> + </bean> + + + + +</beans>
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/resources/ehcache.xml b/archiva-modules/archiva-web/archiva-webapp/src/main/resources/ehcache.xml new file mode 100644 index 000000000..7c7dd7d9a --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/resources/ehcache.xml @@ -0,0 +1,92 @@ +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the License is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + ~ KIND, either express or implied. See the License for the + ~ specific language governing permissions and limitations + ~ under the License. + --> +<ehcache> + <diskStore path="java.io.tmpdir" /> + + <!-- make default cache very short lived --> + + <defaultCache + maxElementsInMemory="100" + maxElementsOnDisk="0" + eternal="false" + overflowToDisk="false" + timeToIdleSeconds="300" + timeToLiveSeconds="600" + memoryStoreEvictionPolicy="LFU" /> + + <!-- + cache Redback classes longer to avoid a lot of SQL queries + See REDBACK-227 + --> + <cache name="defaultJpox" + maxElementsInMemory="10000" + maxElementsOnDisk="0" + eternal="false" + overflowToDisk="false" + timeToIdleSeconds="1800" + timeToLiveSeconds="14400" + memoryStoreEvictionPolicy="LFU" /> + + <cache name="org.apache.archiva.redback.rbac.jdo.JdoOperation" + maxElementsInMemory="10000" + maxElementsOnDisk="0" + eternal="false" + overflowToDisk="false" + timeToIdleSeconds="1800" + timeToLiveSeconds="14400" + memoryStoreEvictionPolicy="LFU" /> + + <cache name="org.apache.archiva.redback.rbac.jdo.JdoPermission" + maxElementsInMemory="10000" + maxElementsOnDisk="0" + eternal="false" + overflowToDisk="false" + timeToIdleSeconds="1800" + timeToLiveSeconds="14400" + memoryStoreEvictionPolicy="LFU" /> + + <cache name="org.apache.archiva.redback.rbac.jdo.JdoResource" + maxElementsInMemory="10000" + maxElementsOnDisk="0" + eternal="false" + overflowToDisk="false" + timeToIdleSeconds="1800" + timeToLiveSeconds="14400" + memoryStoreEvictionPolicy="LFU" /> + + <cache name="org.apache.archiva.redback.rbac.jdo.JdoRole" + maxElementsInMemory="10000" + maxElementsOnDisk="0" + eternal="false" + overflowToDisk="false" + timeToIdleSeconds="1800" + timeToLiveSeconds="14400" + memoryStoreEvictionPolicy="LFU" /> + + <cache name="org.apache.archiva.redback.rbac.jdo.JdoUserAssignment" + maxElementsInMemory="10000" + maxElementsOnDisk="0" + eternal="false" + overflowToDisk="false" + timeToIdleSeconds="300" + timeToLiveSeconds="600" + memoryStoreEvictionPolicy="LFU" /> + +</ehcache> + diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/resources/log4j2.xml b/archiva-modules/archiva-web/archiva-webapp/src/main/resources/log4j2.xml new file mode 100644 index 000000000..c36bbc4e1 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/resources/log4j2.xml @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the License is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + ~ KIND, either express or implied. See the License for the + ~ specific language governing permissions and limitations + ~ under the License. + --> + + +<configuration> + + <properties> + <property name="logsDirectory">${sys:appserver.base}/logs</property> + </properties> + + <appenders> + + <RollingFile name="rolling" fileName="${logsDirectory}/archiva.log" + filePattern="${logsDirectory}/archiva-%d{MM-dd-yyyy}.log"> + <PatternLayout> + <pattern>%d [%t] %-5p %c %x - %m%n</pattern> + </PatternLayout> + <Policies> + <TimeBasedTriggeringPolicy /> + </Policies> + </RollingFile> + + <RollingFile name="auditlog" fileName="${logsDirectory}/archiva-audit.log" + filePattern="${logsDirectory}/logs/archiva-audit-%d{MM-dd-yyyy}.log"> + <PatternLayout> + <pattern>%d{yyyy-MM-dd HH:mm:ss} %m%n</pattern> + </PatternLayout> + <Policies> + <TimeBasedTriggeringPolicy /> + </Policies> + </RollingFile> + + <RollingFile name="redbackAuditLog" fileName="${logsDirectory}/archiva-security-audit.log" + filePattern="${logsDirectory}/archiva-security-audit.log-%d{MM-dd-yyyy}.log"> + <PatternLayout> + <pattern>%d{yyyy-MM-dd HH:mm:ss} - %X{redback.currentUser} - %m%n</pattern> + </PatternLayout> + <Policies> + <TimeBasedTriggeringPolicy /> + </Policies> + </RollingFile> + + </appenders> + <loggers> + + <logger name="org.apache.archiva.redback.struts2.action.AuditEvent" additivity="false" level="info"> + <appender-ref ref="redbackAuditLog" /> + </logger> + + <logger name="org.apache.archiva.AuditLog" additivity="false" level="info"> + <appender-ref ref="auditlog" /> + </logger> + + <!-- INFO level loggers can use the default + <logger name="org.apache.archiva.consumers" level="info"/> + + <logger name="org.apache.archiva" level="info"/> + + + <logger name="org.quartz" level="info"/> + + <logger name="org.apache.jasper" level="info"/> + + <logger name="com.opensymphony.xwork2" level="info"/> + + <logger name="org.apache.struts2" level="info"/> + + --> + + <!-- WebDav objects --> + <logger name="org.apache.archiva.webdav.ArchivaDavResource" level="info"/> + + + <logger name="org.apache.archiva.webdav.ArchivaDavResourceFactory" level="info"/> + + + <!-- squelch noisy objects (for now) --> + <logger name="org.apache.commons" level="warn"/> + + <logger name="net.sf.ehcache" level="warn"/> + + + <!-- retained for Redback --> + <logger name="JPOX" level="warn"/> + + + <logger name="JPOX.MetaData" level="error"/> + + + <logger name="JPOX.RDBMS.SQL" level="error"/> + + + <logger name="SQL" level="error"/> + + + + <logger name="org.apache.commons.configuration.DefaultConfigurationBuilder" level="error"/> + + <!-- debug wagon transfer --> + <!-- + <logger name="org.apache.archiva.proxy.common" level="debug"/> + + --> + <!-- apache httpclient debug content transfer verbose --> + <!-- + <logger name="org.apache.http.wire" level="debug"/> + + --> + <!-- apache httpclient log headers --> + <!-- + <logger name="org.apache.http.headers" level="debug"/> + + --> + + <root level="info"> + <appender-ref ref="rolling"/> + </root> + </loggers> +</configuration> + + diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/resources/org/apache/archiva/redback-security.properties b/archiva-modules/archiva-web/archiva-webapp/src/main/resources/org/apache/archiva/redback-security.properties new file mode 100644 index 000000000..bb883b18a --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/resources/org/apache/archiva/redback-security.properties @@ -0,0 +1,29 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# -------------------------------------------------------------------- +# Email Settings + +# The subject line for the email message. +email.validation.subject=Welcome to Archiva + +# Feedback page +email.feedback.path=http://archiva.apache.org/mail-lists.html + +email.url.path=index.html
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/applicationContext.xml b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/applicationContext.xml new file mode 100644 index 000000000..704358dec --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/applicationContext.xml @@ -0,0 +1,189 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the License is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + ~ KIND, either express or implied. See the License for the + ~ specific language governing permissions and limitations + ~ under the License. + --> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:context="http://www.springframework.org/schema/context" + xmlns:task="http://www.springframework.org/schema/task" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-3.0.xsd + http://www.springframework.org/schema/context + http://www.springframework.org/schema/context/spring-context-3.0.xsd + http://www.springframework.org/schema/task + http://www.springframework.org/schema/task/spring-task-3.0.xsd"> + + <context:property-placeholder location="classpath:application.properties"/> + + <alias name="userConfiguration#archiva" alias="userConfiguration#default" /> + + <bean id="loggerManager" class="org.codehaus.plexus.logging.slf4j.Slf4jLoggerManager" + init-method="initialize"/> + + <!-- only here to cleanup temp indexes for groups increase number if use for something else --> + <task:executor id="springExecutor" pool-size="2"/> + <task:scheduler id="springScheduler" pool-size="2"/> + <task:annotation-driven executor="springExecutor" scheduler="springScheduler"/> + + <alias name="repositoryStatisticsManager#default" alias="repositoryStatisticsManager"/> + <!-- TODO olamy need to find a more dynamic way if using jcr impl --> + <alias name="repositorySessionFactory#jcr" alias="repositorySessionFactory"/> + + <bean id="mailSession" class="org.springframework.jndi.JndiObjectFactoryBean"> + <property name="jndiName" value="java:comp/env/mail/Session"> + </property> + </bean> + + <bean name="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> + <property name="session" ref="mailSession"/> + </bean> + + <!-- START SNIPPET: configuration-files-list --> + <bean name="commons-configuration" class="org.apache.archiva.redback.components.registry.commons.CommonsConfigurationRegistry"> + <property name="properties"> + <value> + <![CDATA[ + <configuration> + <system/> + <jndi prefix="java:comp/env" config-optional="true"/> + <xml fileName="${user.home}/.m2/archiva.xml" config-optional="true" + config-name="org.apache.archiva.user" + config-at="org.apache.archiva"/> + <xml fileName="${user.home}/.m2/shared.xml" config-optional="true" + config-name="org.apache.maven.shared.app.user" config-at="org.apache.maven.shared.app" + config-forceCreate="true"/> + <properties fileName="${user.home}/.m2/security.properties" config-optional="true" + config-at="org.apache.archiva.redback"/> + <properties fileName="${user.home}/.m2/archiva.properties" config-optional="true" + config-at="org.apache.archiva.redback"/> + <xml fileName="${appserver.base}/conf/archiva.xml" config-optional="true" + config-name="org.apache.archiva.base" + config-at="org.apache.archiva"/> + <xml fileName="${appserver.base}/conf/shared.xml" config-optional="true" + config-name="org.apache.maven.shared.app.base" config-at="org.apache.maven.shared.app"/> + <xml fileName="${appserver.base}/conf/common.xml" config-optional="true"/> + <properties fileName="${appserver.base}/conf/security.properties" config-optional="true" + config-at="org.apache.archiva.redback"/> + <xml fileName="${appserver.home}/conf/archiva.xml" config-optional="true" + config-at="org.apache.archiva"/> + <xml fileName="${appserver.home}/conf/shared.xml" config-optional="true" + config-at="org.apache.maven.shared.app"/> + <xml fileName="${appserver.home}/conf/common.xml" config-optional="true"/> + <properties fileName="${appserver.home}/conf/security.properties" config-optional="true" + config-at="org.apache.archiva.redback"/> + <properties fileName="org/apache/archiva/redback-security.properties" config-at="org.apache.archiva.redback"/> + </configuration> + ]]> + </value> + </property> + </bean> + <!-- END SNIPPET: configuration-files-list --> + + <bean name="jdoFactory#users" class="org.apache.archiva.redback.components.jdo.DataSourceConfigurableJdoFactory"> + <property name="connectionFactoryName" value="java:comp/env/jdbc/users"/> + <property name="shutdownConnectionFactoryName" value="java:comp/env/jdbc/usersShutdown"/> + <property name="persistenceManagerFactoryClass" value="org.jpox.PersistenceManagerFactoryImpl"/> + <property name="otherProperties"> + <props> + <prop key="org.jpox.autoCreateSchema">true</prop> + <prop key="org.jpox.validateTables">false</prop> + <prop key="org.jpox.validateConstraints">false</prop> + <prop key="org.jpox.validateColumns">false</prop> + <prop key="org.jpox.autoStartMechanism">None</prop> + <prop key="org.jpox.transactionIsolation">READ_COMMITTED</prop> + <prop key="org.jpox.poid.transactionIsolation">READ_COMMITTED</prop> + <prop key="org.jpox.rdbms.dateTimezone">JDK_DEFAULT_TIMEZONE</prop> + <!-- NEEDED FOR MYSQL UTF-8 Databases --> + <prop key="org.jpox.rdbms.stringDefaultLength">255</prop> + + <!-- NEEDED FOR POSTGRES, But causes problems in other JDBC implementations. + <prop key="org.jpox.identifier.case">PreserveCase</prop> + --> + + <!-- cache activation --> + <prop key="org.jpox.cache.level2">true</prop> + <prop key="org.jpox.cache.level2.type">ehcacheclassbased</prop> + <prop key="org.jpox.cache.level2.cacheName">defaultJpox</prop> + <prop key="org.jpox.cache.level2.configurationFile">/ehcache.xml</prop> + </props> + </property> + </bean> + + + <bean name="scheduler" class="org.apache.archiva.redback.components.scheduler.DefaultScheduler"> + <property name="properties"> + <props> + <prop key="org.quartz.scheduler.instanceName">scheduler1</prop> + <prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop> + <prop key="org.quartz.threadPool.threadCount">2</prop> + <prop key="org.quartz.threadPool.threadPriority">4</prop> + <prop key="org.quartz.jobStore.class">org.quartz.simpl.RAMJobStore</prop> + </props> + </property> + </bean> + + <alias name="environmentCheck#archiva-locked-admin-check" alias="environmentCheck#locked-admin-check"/> + <alias name="userManager#archiva" alias="userManager#configurable"/> + <alias name="authenticator#archiva" alias="authenticator#user-manager"/> + + <alias name="ldapConnectionFactory#archiva" alias="ldapConnectionFactory"/> + <alias name="ldapConnectionFactory#archiva" alias="ldapConnectionFactory#configurable"/> + + <!-- + <bean name="mimeTpes" class="org.apache.archiva.webdav.util.MimeTypes"> + <property name="resource" value="archiva-mime-types.txt"/> + </bean> + --> + <!-- for change configuration of the users cache --> + <bean name="cache#users" class="org.apache.archiva.redback.components.cache.ehcache.EhcacheCache" + init-method="initialize"> + <property name="diskPersistent" value="false"/> + <property name="eternal" value="false"/> + <property name="maxElementsInMemory" value="1000"/> + <property name="memoryEvictionPolicy" value="LRU"/> + <property name="name" value="usersCache"/> + <property name="timeToIdleSeconds" value="14400"/> + <property name="timeToLiveSeconds" value="14400"/> + </bean> + + <bean name="cache#url-failures-cache" class="org.apache.archiva.redback.components.cache.ehcache.EhcacheCache" lazy-init="true" + destroy-method="dispose"> + <property name="diskExpiryThreadIntervalSeconds" value="600"/> + <property name="diskPersistent" value="true"/> + <property name="diskStorePath" value="${java.io.tmpdir}/archiva/urlcache"/> + <property name="maxElementsInMemory" value="1000"/> + <property name="memoryEvictionPolicy" value="LRU"/> + <property name="name" value="url-failures-cache"/> + <property name="overflowToDisk" value="false"/> + <!-- 45 minutes = 2700 seconds --> + <property name="timeToIdleSeconds" value="2700"/> + <!-- 30 minutes = 1800 seconds --> + <property name="timeToLiveSeconds" value="1800"/> + </bean> + + <!-- override jcr repository location --> + <!-- START SNIPPET: jcr-location --> + <!-- + <bean id="jcr-config" class="org.apache.archiva.metadata.repository.jcr.ArchivaJcrRepositoryConfig" factory-method="create"> + <constructor-arg value="${appserver.base}/conf/repository.xml"/> + <constructor-arg value="${appserver.base}/data/jcr"/> + </bean> + --> + <!-- END SNIPPET: jcr-location --> + +</beans> diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/web.xml b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..8d8515292 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,146 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + ~ Copyright 2005-2006 The Apache Software Foundation. + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + + +<web-app xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> + + <display-name>Apache Archiva</display-name> + + <context-param> + <param-name>contextConfigLocation</param-name> + <param-value> + classpath*:META-INF/spring-context.xml, + /WEB-INF/applicationContext.xml + </param-value> + </context-param> + + <filter> + <filter-name>encodingFilter</filter-name> + <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> + <init-param> + <param-name>encoding</param-name> + <param-value>UTF-8</param-value> + </init-param> + <init-param> + <param-name>forceEncoding</param-name> + <param-value>true</param-value> + </init-param> + </filter> + + <filter-mapping> + <filter-name>encodingFilter</filter-name> + <url-pattern>/*</url-pattern> + </filter-mapping> + + <listener> + <listener-class> + org.springframework.web.context.ContextLoaderListener + </listener-class> + </listener> + <listener> + <!-- TODO: some Spring technique for this? --> + <listener-class> + org.apache.archiva.web.startup.ArchivaStartup + </listener-class> + </listener> + + <listener> + <listener-class>net.sf.ehcache.constructs.web.ShutdownListener</listener-class> + </listener> + + <!-- to cleanup temporary group index created during a session --> + <listener> + <listener-class>org.apache.archiva.webdav.util.TemporaryGroupIndexSessionCleaner</listener-class> + </listener> + + <servlet> + <servlet-name>RepositoryServlet</servlet-name> + <servlet-class> + org.apache.archiva.webdav.RepositoryServlet + </servlet-class> + <!-- Loading this on startup so as to take advantage of configuration listeners --> + <load-on-startup>1</load-on-startup> + </servlet> + + <servlet> + <servlet-name>RestDocumentation</servlet-name> + <servlet-class>org.apache.archiva.web.docs.RestDocsServlet</servlet-class> + <load-on-startup>3</load-on-startup> + </servlet> + + + <servlet> + <servlet-name>RssFeedServlet</servlet-name> + <servlet-class> + org.apache.archiva.web.rss.RssFeedServlet + </servlet-class> + </servlet> + + <servlet-mapping> + <servlet-name>RssFeedServlet</servlet-name> + <url-pattern>/feeds/*</url-pattern> + </servlet-mapping> + + <servlet-mapping> + <servlet-name>RestDocumentation</servlet-name> + <url-pattern>/rest-docs/*</url-pattern> + </servlet-mapping> + + <servlet-mapping> + <servlet-name>RepositoryServlet</servlet-name> + <url-pattern>/repository/*</url-pattern> + </servlet-mapping> + + + + <resource-ref> + <res-ref-name>jdbc/users</res-ref-name> + <res-type>javax.sql.DataSource</res-type> + <res-auth>Container</res-auth> + <res-sharing-scope>Shareable</res-sharing-scope> + </resource-ref> + <resource-ref> + <res-ref-name>mail/Session</res-ref-name> + <res-type>javax.mail.Session</res-type> + <res-auth>Container</res-auth> + <res-sharing-scope>Shareable</res-sharing-scope> + </resource-ref> + + <servlet> + <servlet-name>CXFServlet</servlet-name> + <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> + <load-on-startup>1</load-on-startup> + </servlet> + + <servlet-mapping> + <servlet-name>CXFServlet</servlet-name> + <url-pattern>/restServices/*</url-pattern> + </servlet-mapping> + + <welcome-file-list> + <welcome-file>index.html</welcome-file> + </welcome-file-list> + + <session-config> + <!-- 30 minutes session timeout --> + <session-timeout>30</session-timeout> + </session-config> + +</web-app> diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/archiva.css b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/archiva.css new file mode 100644 index 000000000..cf688aa23 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/archiva.css @@ -0,0 +1,190 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* medium-spinner */ +#medium-spinner { + z-index: 20001; +} + +.ar-multiselect .ar-multiselect-column { + float: left; + width: 17em; +} + +.ar-multiselect .ar-multiselect-center { + float: left; + width: 3em; +} + +.ar-multiselect-center ul { + list-style: none; + margin: 3px 0 2px 6px +} + +.ar-multiselect-right { + margin-left: 2em +} + +.modified { + border:2px solid #fbc7c6; +} + +.modified td{ + border-top:2px solid #fbc7c6; + border:2px solid #fbc7c6; +} + +.draggable-item { + cursor: move; + margin-bottom: 12px; + margin-left: 4px; + min-height: 2px; + padding: 12px; + border: 2px dotted #ddd; + margin-left: 2em +} + +.network-proxy-remote-item{ + margin-bottom: 12px; + min-height: 2px; + padding: 12px; + border: 2px dotted #ddd; + margin-left: 2em +} + +.dotted{ + margin-bottom: 12px; + min-height: 2px; + padding: 12px; + border: 2px dotted #ddd; + margin-left: 2em +} + +.browse-list{ + list-style-image: url("../images/folder.png") +} +.browse-list-project{ + list-style-image: url("../images/folder-saved-search.png"); +} + +.package-list{ + list-style-image: url("../images/package-x-generic.png"); +} + +.force-upper-case{ + text-transform: uppercase; +} + +.dropdown-menu { + max-width: 920px; +} +.ui-menu-item { + cursor: pointer; +} + +.ui-autocomplete-loading{ + background:url('../images/small-spinner.gif') no-repeat right center; +} + +.nav .archiva-nav-header{ + font-size: 12px; +} + +footer { + border-top: 1px solid #CCCCCC; + color: #333333; + margin-top: 1em; + padding-bottom: 30px; + padding-top: 10px; +} + + +/* CSS for loading message */ +#loadingDiv { + position: absolute; + left: 45%; + bottom: 50%; + z-index: 20001; + height: auto; + border: 1px solid #ccc; +} +#loadingDiv a { + color: #225588; +} + +#loadingDiv .loading-indicator { + background: white; + color: #444; + font: bold 12px tahoma; + padding: 10px; + margin: 0; + height: auto; +} + +.navbar .brand { + color: #555555; + display: block; + float: left; + font-size: 20px; + font-weight: 200; + margin-left: -20px; + padding: 5px 5px; + text-shadow: 0 1px 0 #FFFFFF; +} + +.sidebar-nav { + padding: 9px 0; +} + +.page-header { + border-bottom: 1px solid #EEEEEE; + margin: 15px 0 20px; + padding-bottom: 3px; +} + +.cursor-hand:hover { + cursor: pointer; +} + + +code { + background: none repeat scroll 0 0 #EEEEEE; + border: 1px solid #DDDDDD; + color: #555555; + display: block; + font: 1.1em "Lucida Sans Unicode",serif; + margin-bottom: 12px; + max-height: 300px; + overflow: auto; + padding: 8px 10px; + white-space: pre; + vertical-align: baseline; +} + +ol.linenums { + margin-bottom: 0; + margin-top: 0; + padding-left: 5px; +} + +.ui-widget { + color: #333333; + font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; + font-size: 14px; +}
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/bootstrap.2.2.1.css b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/bootstrap.2.2.1.css new file mode 100644 index 000000000..1b519e220 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/bootstrap.2.2.1.css @@ -0,0 +1,5893 @@ +/*! + * Bootstrap v2.2.1 + * + * 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. + */ + +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; +} + +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; +} + +.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; +} + +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 { + 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; +} + +.text-warning { + color: #c09853; +} + +a.text-warning:hover { + color: #a47e3c; +} + +.text-error { + color: #b94a48; +} + +a.text-error:hover { + color: #953b39; +} + +.text-info { + color: #3a87ad; +} + +a.text-info:hover { + color: #2d6987; +} + +.text-success { + color: #468847; +} + +a.text-success:hover { + color: #356635; +} + +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; +} + +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: 16px; + font-weight: 300; + line-height: 25px; +} + +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; + 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; + 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; + cursor: pointer; +} + +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 > 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 > 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 > 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 > 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:required:invalid, +textarea:focus:required:invalid, +select:focus:required:invalid { + color: #b94a48; + border-color: #ee5f5b; +} + +input:focus:required:invalid:focus, +textarea:focus:required:invalid:focus, +select:focus:required: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 { + margin-bottom: 5px; + font-size: 0; + white-space: nowrap; +} + +.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 { + 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 { + 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, +.input-append select + .btn-group .btn, +.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-append .add-on, +.input-append .btn, +.input-append .btn-group { + margin-left: -1px; +} + +.input-append .add-on:last-child, +.input-append .btn:last-child { + -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 { + 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-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 { + -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 { + -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 tfoot:last-child tr:last-child td:first-child { + -webkit-border-radius: 0 0 0 4px; + -moz-border-radius: 0 0 0 4px; + border-radius: 0 0 0 4px; + -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 tfoot:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; +} + +.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/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:hover > [class*=" icon-"], +.dropdown-menu > .active > a > [class^="icon-"], +.dropdown-menu > .active > a > [class*=" icon-"], +.dropdown-submenu:hover > a > [class^="icon-"], +.dropdown-submenu:hover > 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 { + 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 { + 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 { + color: #333333; + 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 { + color: #999999; +} + +.dropdown-menu .disabled > a:hover { + text-decoration: none; + cursor: default; + background-color: transparent; + background-image: none; +} + +.open { + *z-index: 1000; +} + +.open > .dropdown-menu { + display: block; +} + +.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 { + 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 { + 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; + *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 #bbbbbb; + *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: #a2a2a2; + -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: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 { + color: #333333; + text-decoration: none; + background-color: #e6e6e6; + *background-color: #d9d9d9; + /* Buttons in IE7 don't get borders, so darken on hover */ + + 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-color: #e6e6e6; + background-color: #d9d9d9 \9; + 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-color: #e6e6e6; + 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: 2px; +} + +.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 { + padding: 1px 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 { + border-color: #c5c5c5; + border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); +} + +.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: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: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: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: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: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: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 { + color: #005580; + text-decoration: underline; + background-color: transparent; +} + +.btn-link[disabled]:hover { + 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 { + font-size: 14px; +} + +.btn-group > .btn-mini { + font-size: 11px; +} + +.btn-group > .btn-small { + font-size: 12px; +} + +.btn-group > .btn-large { + font-size: 16px; +} + +.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-mini .caret, +.btn-small .caret, +.btn-large .caret { + margin-top: 6px; +} + +.btn-large .caret { + border-top-width: 5px; + border-right-width: 5px; + border-left-width: 5px; +} + +.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; + 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; + color: #c09853; + 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 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-danger, +.alert-error { + color: #b94a48; + background-color: #f2dede; + border-color: #eed3d7; +} + +.alert-info { + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1; +} + +.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 { + text-decoration: none; + background-color: #eeeeee; +} + +.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 { + 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 { + border-color: #eeeeee #eeeeee #dddddd; +} + +.nav-tabs > .active > a, +.nav-tabs > .active > a:hover { + 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 { + 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 { + 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 { + 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 { + cursor: pointer; +} + +.nav-tabs .open .dropdown-toggle, +.nav-pills .open .dropdown-toggle, +.nav > li.dropdown.open.active > a:hover { + 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 { + border-top-color: #ffffff; + border-bottom-color: #ffffff; + opacity: 1; + filter: alpha(opacity=100); +} + +.tabs-stacked .open > a:hover { + 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 { + border-top-color: #ddd; + border-bottom-color: transparent; +} + +.tabs-below > .nav-tabs > .active > a, +.tabs-below > .nav-tabs > .active > a:hover { + 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 { + border-color: #eeeeee #dddddd #eeeeee #eeeeee; +} + +.tabs-left > .nav-tabs .active > a, +.tabs-left > .nav-tabs .active > a:hover { + 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 { + border-color: #eeeeee #eeeeee #eeeeee #dddddd; +} + +.tabs-right > .nav-tabs .active > a, +.tabs-right > .nav-tabs .active > a:hover { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: #ffffff; +} + +.nav > .disabled > a { + color: #999999; +} + +.nav > .disabled > a:hover { + text-decoration: none; + cursor: default; + background-color: transparent; +} + +.navbar { + *position: relative; + *z-index: 2; + margin-bottom: 20px; + overflow: visible; + color: #777777; +} + +.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 { + text-decoration: none; +} + +.navbar-text { + margin-bottom: 0; + line-height: 40px; +} + +.navbar-link { + color: #777777; +} + +.navbar-link:hover { + 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 { + 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: 6px; + 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: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.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 { + color: #999999; +} + +.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 { + color: #ffffff; +} + +.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 { + 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 > .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: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 .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 > .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 { + 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: 1px 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 { + 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 > 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: 50%; + left: 50%; + z-index: 1050; + width: 560px; + margin: -250px 0 0 -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: 50%; +} + +.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 { + 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; + padding: 5px; + font-size: 11px; + opacity: 0; + filter: alpha(opacity=0); + visibility: visible; +} + +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} + +.tooltip.top { + margin-top: -3px; +} + +.tooltip.right { + margin-left: 3px; +} + +.tooltip.bottom { + margin-top: 3px; +} + +.tooltip.left { + margin-left: -3px; +} + +.tooltip-inner { + max-width: 200px; + padding: 3px 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; + width: 236px; + padding: 1px; + 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-content { + padding: 9px 14px; +} + +.popover-content p, +.popover-content ul, +.popover-content ol { + margin-bottom: 0; +} + +.popover .arrow, +.popover .arrow:after { + position: absolute; + display: inline-block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.popover .arrow:after { + z-index: -1; + content: ""; +} + +.popover.top .arrow { + bottom: -10px; + left: 50%; + margin-left: -10px; + border-top-color: #ffffff; + border-width: 10px 10px 0; +} + +.popover.top .arrow:after { + bottom: -1px; + left: -11px; + border-top-color: rgba(0, 0, 0, 0.25); + border-width: 11px 11px 0; +} + +.popover.right .arrow { + top: 50%; + left: -10px; + margin-top: -10px; + border-right-color: #ffffff; + border-width: 10px 10px 10px 0; +} + +.popover.right .arrow:after { + bottom: -11px; + left: -1px; + border-right-color: rgba(0, 0, 0, 0.25); + border-width: 11px 11px 11px 0; +} + +.popover.bottom .arrow { + top: -10px; + left: 50%; + margin-left: -10px; + border-bottom-color: #ffffff; + border-width: 0 10px 10px; +} + +.popover.bottom .arrow:after { + top: -1px; + left: -11px; + border-bottom-color: rgba(0, 0, 0, 0.25); + border-width: 0 11px 11px; +} + +.popover.left .arrow { + top: 50%; + right: -10px; + margin-top: -10px; + border-left-color: #ffffff; + border-width: 10px 0 10px 10px; +} + +.popover.left .arrow:after { + right: -1px; + bottom: -11px; + border-left-color: rgba(0, 0, 0, 0.25); + border-width: 11px 0 11px 11px; +} + +.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 { + 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; +} + +a.label:hover, +a.badge:hover { + 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 .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 .item > img { + display: block; + line-height: 1; +} + +.carousel .active, +.carousel .next, +.carousel .prev { + display: block; +} + +.carousel .active { + left: 0; +} + +.carousel .next, +.carousel .prev { + position: absolute; + top: 0; + width: 100%; +} + +.carousel .next { + left: 100%; +} + +.carousel .prev { + left: -100%; +} + +.carousel .next.left, +.carousel .prev.right { + left: 0; +} + +.carousel .active.left { + left: -100%; +} + +.carousel .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 { + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} + +.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; +} diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/application.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/application.png Binary files differnew file mode 100755 index 000000000..1dee9e366 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/application.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/code.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/code.png Binary files differnew file mode 100755 index 000000000..0c76bd129 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/code.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/css.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/css.png Binary files differnew file mode 100755 index 000000000..f907e44b3 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/css.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/db.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/db.png Binary files differnew file mode 100755 index 000000000..bddba1f98 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/db.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/doc.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/doc.png Binary files differnew file mode 100755 index 000000000..ae8ecbf47 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/doc.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/file.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/file.png Binary files differnew file mode 100755 index 000000000..8b8b1ca00 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/file.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/film.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/film.png Binary files differnew file mode 100755 index 000000000..b0ce7bb19 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/film.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/flash.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/flash.png Binary files differnew file mode 100755 index 000000000..5769120b1 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/flash.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/folder-closed.gif b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/folder-closed.gif Binary files differnew file mode 100755 index 000000000..541107888 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/folder-closed.gif diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/folder.gif b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/folder.gif Binary files differnew file mode 100755 index 000000000..2b31631ca --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/folder.gif diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/html.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/html.png Binary files differnew file mode 100755 index 000000000..6ed2490ed --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/html.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/java.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/java.png Binary files differnew file mode 100755 index 000000000..b7bfcd15f --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/java.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/linux.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/linux.png Binary files differnew file mode 100755 index 000000000..52699bfee --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/linux.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/music.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/music.png Binary files differnew file mode 100755 index 000000000..a8b3ede3d --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/music.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/pdf.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/pdf.png Binary files differnew file mode 100755 index 000000000..8f8095e46 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/pdf.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/php.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/php.png Binary files differnew file mode 100755 index 000000000..7868a2594 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/php.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/picture.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/picture.png Binary files differnew file mode 100755 index 000000000..4a158fef7 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/picture.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ppt.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ppt.png Binary files differnew file mode 100755 index 000000000..c4eff0387 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ppt.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/psd.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/psd.png Binary files differnew file mode 100755 index 000000000..73c5b3f24 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/psd.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ruby.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ruby.png Binary files differnew file mode 100755 index 000000000..f59b7c436 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ruby.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/script.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/script.png Binary files differnew file mode 100755 index 000000000..63fe6ceff --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/script.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/select2.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/select2.png Binary files differnew file mode 100755 index 000000000..1d804ffb9 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/select2.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/select2x2.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/select2x2.png Binary files differnew file mode 100755 index 000000000..4bdd5c961 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/select2x2.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/spinner.gif b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/spinner.gif Binary files differnew file mode 100755 index 000000000..85b99d46b --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/spinner.gif diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/txt.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/txt.png Binary files differnew file mode 100755 index 000000000..813f712f7 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/txt.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_flat_0_aaaaaa_40x100.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_flat_0_aaaaaa_40x100.png Binary files differnew file mode 100755 index 000000000..5b5dab2ab --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_flat_0_aaaaaa_40x100.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_flat_75_ffffff_40x100.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_flat_75_ffffff_40x100.png Binary files differnew file mode 100755 index 000000000..ac8b229af --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_flat_75_ffffff_40x100.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_glass_55_fbf9ee_1x400.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_glass_55_fbf9ee_1x400.png Binary files differnew file mode 100755 index 000000000..ad3d6346e --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_glass_55_fbf9ee_1x400.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_glass_65_ffffff_1x400.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_glass_65_ffffff_1x400.png Binary files differnew file mode 100755 index 000000000..42ccba269 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_glass_65_ffffff_1x400.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_glass_75_dadada_1x400.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_glass_75_dadada_1x400.png Binary files differnew file mode 100755 index 000000000..5a46b47cb --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_glass_75_dadada_1x400.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_glass_75_e6e6e6_1x400.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_glass_75_e6e6e6_1x400.png Binary files differnew file mode 100755 index 000000000..86c2baa65 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_glass_75_e6e6e6_1x400.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_glass_75_ffffff_1x400.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_glass_75_ffffff_1x400.png Binary files differnew file mode 100755 index 000000000..e65ca1297 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_glass_75_ffffff_1x400.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_glass_95_fef1ec_1x400.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_glass_95_fef1ec_1x400.png Binary files differnew file mode 100755 index 000000000..4443fdc1a --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_glass_95_fef1ec_1x400.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png Binary files differnew file mode 100755 index 000000000..7c9fa6c6e --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_inset-soft_95_fef1ec_1x100.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_inset-soft_95_fef1ec_1x100.png Binary files differnew file mode 100755 index 000000000..0e05810ff --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-bg_inset-soft_95_fef1ec_1x100.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-icons_222222_256x240.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-icons_222222_256x240.png Binary files differnew file mode 100755 index 000000000..b273ff111 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-icons_222222_256x240.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-icons_2e83ff_256x240.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-icons_2e83ff_256x240.png Binary files differnew file mode 100755 index 000000000..09d1cdc85 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-icons_2e83ff_256x240.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-icons_454545_256x240.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-icons_454545_256x240.png Binary files differnew file mode 100755 index 000000000..59bd45b90 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-icons_454545_256x240.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-icons_888888_256x240.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-icons_888888_256x240.png Binary files differnew file mode 100755 index 000000000..6d02426c1 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-icons_888888_256x240.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-icons_cd0a0a_256x240.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-icons_cd0a0a_256x240.png Binary files differnew file mode 100755 index 000000000..2ab019b73 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-icons_cd0a0a_256x240.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-icons_f6cf3b_256x240.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-icons_f6cf3b_256x240.png Binary files differnew file mode 100644 index 000000000..c9869351a --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/ui-icons_f6cf3b_256x240.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/xls.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/xls.png Binary files differnew file mode 100755 index 000000000..b977d7e52 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/xls.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/zip.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/zip.png Binary files differnew file mode 100755 index 000000000..fd4bbccdf --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/images/zip.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/jquery-ui-1.9.2.custom.min.css b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/jquery-ui-1.9.2.custom.min.css new file mode 100755 index 000000000..e96496989 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/jquery-ui-1.9.2.custom.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.2 - 2012-11-23 +* http://jqueryui.com +* Includes: jquery.ui.core.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css +* To view and modify this theme, visit http://jqueryui.com/themeroller/ +* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{zoom:1}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:absolute;top:0;left:0;width:100%;height:100%}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin-top:2px;padding:.5em .5em .5em .7em;zoom:1}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-noicons{padding-left:.7em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto;zoom:1}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}* html .ui-autocomplete{width:1px}.ui-button{display:inline-block;position:relative;padding:0;margin-right:.1em;cursor:pointer;text-align:center;zoom:1;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:1.4}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month-year{width:100%}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:49%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0em}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current{float:right}.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-datepicker-cover{position:absolute;z-index:-1;filter:mask();top:-4px;left:-4px;width:200px;height:200px}.ui-dialog{position:absolute;top:0;left:0;padding:.2em;width:300px;overflow:hidden}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 16px .1em 0}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:19px;margin:-10px 0 0 0;padding:1px;height:18px}.ui-dialog .ui-dialog-titlebar-close span{display:block;margin:1px}.ui-dialog .ui-dialog-titlebar-close:hover,.ui-dialog .ui-dialog-titlebar-close:focus{padding:0}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto;zoom:1}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin:.5em 0 0 0;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:14px;height:14px;right:3px;bottom:3px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-menu{list-style:none;padding:2px;margin:0;display:block;outline:none}.ui-menu .ui-menu{margin-top:-3px;position:absolute}.ui-menu .ui-menu-item{margin:0;padding:0;zoom:1;width:100%}.ui-menu .ui-menu-divider{margin:5px -2px 5px -2px;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.5;zoom:1;font-weight:normal}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px}.ui-menu .ui-state-disabled{font-weight:normal;margin:.4em 0 .2em;line-height:1.5}.ui-menu .ui-state-disabled a{cursor:default}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em}.ui-menu .ui-menu-icon{position:static;float:right}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em;zoom:1}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav li a{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-tabs-loading a{cursor:text}.ui-tabs .ui-tabs-nav li a,.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}* html .ui-tooltip{background-image:none}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Verdana,Arial,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,Arial,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #aaa;background:#fff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x;color:#222}.ui-widget-content a{color:#222}.ui-widget-header{border:1px solid #aaa;background:#ccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x;color:#222;font-weight:bold}.ui-widget-header a{color:#222}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #d3d3d3;background:#e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#555}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #999;background:#dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited{color:#212121;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #aaa;background:#fff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fcefa1;background:#fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x;color:#363636}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x;color:#cd0a0a}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px;background-image:url(images/ui-icons_222222_256x240.png)}.ui-widget-content .ui-icon{background-image:url(images/ui-icons_222222_256x240.png)}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_222222_256x240.png)}.ui-state-default .ui-icon{background-image:url(images/ui-icons_888888_256x240.png)}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_454545_256x240.png)}.ui-state-active .ui-icon{background-image:url(images/ui-icons_454545_256x240.png)}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_2e83ff_256x240.png)}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_cd0a0a_256x240.png)}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{-moz-border-radius-topleft:4px;-webkit-border-top-left-radius:4px;-khtml-border-top-left-radius:4px;border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{-moz-border-radius-topright:4px;-webkit-border-top-right-radius:4px;-khtml-border-top-right-radius:4px;border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{-moz-border-radius-bottomleft:4px;-webkit-border-bottom-left-radius:4px;-khtml-border-bottom-left-radius:4px;border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{-moz-border-radius-bottomright:4px;-webkit-border-bottom-right-radius:4px;-khtml-border-bottom-right-radius:4px;border-bottom-right-radius:4px}.ui-widget-overlay{background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30);-moz-border-radius:8px;-khtml-border-radius:8px;-webkit-border-radius:8px;border-radius:8px}
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/jquery.fileupload-ui.css b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/jquery.fileupload-ui.css new file mode 100644 index 000000000..e36a93df3 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/jquery.fileupload-ui.css @@ -0,0 +1,84 @@ +@charset 'UTF-8'; +/* + * jQuery File Upload UI Plugin CSS 6.3 + * https://github.com/blueimp/jQuery-File-Upload + * + * Copyright 2010, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/MIT + */ + +.fileinput-button { + position: relative; + overflow: hidden; + float: left; + margin-right: 4px; +} +.fileinput-button input { + position: absolute; + top: 0; + right: 0; + margin: 0; + border: solid transparent; + border-width: 0 0 100px 200px; + opacity: 0; + filter: alpha(opacity=0); + -moz-transform: translate(-300px, 0) scale(4); + direction: ltr; + cursor: pointer; +} +.fileupload-buttonbar .btn, +.fileupload-buttonbar .toggle { + margin-bottom: 5px; +} +.files .progress { + width: 200px; +} +.progress-animated .bar { + background: url(../img/progressbar.gif) !important; + filter: none; +} +.fileupload-loading { + position: absolute; + left: 50%; + width: 128px; + height: 128px; + background: url(../img/loading.gif) center no-repeat; + display: none; +} +.fileupload-processing .fileupload-loading { + display: block; +} + +/* Fix for IE 6: */ +*html .fileinput-button { + line-height: 22px; + margin: 1px -3px 0 0; +} + +/* Fix for IE 7: */ +*+html .fileinput-button { + margin: 1px 0 0 0; +} + +@media (max-width: 480px) { + .files .btn span { + display: none; + } + .files .preview * { + width: 40px; + } + .files .name * { + width: 80px; + display: inline-block; + word-wrap: break-word; + } + .files .progress { + width: 20px; + } + .files .delete { + width: 60px; + } +} diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/jquery.ui.1.8.16.ie.css b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/jquery.ui.1.8.16.ie.css new file mode 100755 index 000000000..b24b9fb8a --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/jquery.ui.1.8.16.ie.css @@ -0,0 +1,6 @@ + +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-left, .ui-corner-bottom{ border-radius:0px;} +.ui-state-active,.ui-tabs-selected { border-radius:0px;} +.ui-tabs-selected { border-radius:0px;} +.ui-tabs .ui-tabs-nav li{ filter:none;} +.ui-tabs .ui-tabs-nav li a { border-radius:0px; } diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/jqueryFileTree.css b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/jqueryFileTree.css new file mode 100755 index 000000000..073d1fdec --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/jqueryFileTree.css @@ -0,0 +1,91 @@ +UL.jqueryFileTree {
+ font-family: Verdana, sans-serif;
+ font-size: 11px;
+ line-height: 18px;
+ padding: 0px;
+ margin: 0px;
+}
+
+UL.jqueryFileTree LI {
+ list-style: none;
+ padding: 0px;
+ padding-left: 20px;
+ margin: 0px;
+ white-space: nowrap;
+}
+
+UL.jqueryFileTree A {
+ color: #333;
+ text-decoration: none;
+ display: block;
+ padding: 0px 2px;
+}
+
+UL.jqueryFileTree A:hover {
+ background: #BDF;
+}
+
+/* Core Styles */
+.jqueryFileTree LI.directory { background: url(images/folder-closed.gif) left top no-repeat; }
+.jqueryFileTree LI.expanded { background: url(images/folder.gif) left top no-repeat; }
+.jqueryFileTree LI.file { background: url(images/file.png) left top no-repeat; }
+.jqueryFileTree LI.wait { background: url(images/spinner.gif) left top no-repeat; }
+/* File Extensions*/
+.jqueryFileTree LI.ext_3gp { background: url(images/film.png) left top no-repeat; }
+.jqueryFileTree LI.ext_afp { background: url(images/code.png) left top no-repeat; }
+.jqueryFileTree LI.ext_afpa { background: url(images/code.png) left top no-repeat; }
+.jqueryFileTree LI.ext_asp { background: url(images/code.png) left top no-repeat; }
+.jqueryFileTree LI.ext_aspx { background: url(images/code.png) left top no-repeat; }
+.jqueryFileTree LI.ext_avi { background: url(images/film.png) left top no-repeat; }
+.jqueryFileTree LI.ext_bat { background: url(images/application.png) left top no-repeat; }
+.jqueryFileTree LI.ext_bmp { background: url(images/picture.png) left top no-repeat; }
+.jqueryFileTree LI.ext_c { background: url(images/code.png) left top no-repeat; }
+.jqueryFileTree LI.ext_cfm { background: url(images/code.png) left top no-repeat; }
+.jqueryFileTree LI.ext_cgi { background: url(images/code.png) left top no-repeat; }
+.jqueryFileTree LI.ext_com { background: url(images/application.png) left top no-repeat; }
+.jqueryFileTree LI.ext_cpp { background: url(images/code.png) left top no-repeat; }
+.jqueryFileTree LI.ext_css { background: url(images/css.png) left top no-repeat; }
+.jqueryFileTree LI.ext_doc { background: url(images/doc.png) left top no-repeat; }
+.jqueryFileTree LI.ext_exe { background: url(images/application.png) left top no-repeat; }
+.jqueryFileTree LI.ext_gif { background: url(images/picture.png) left top no-repeat; }
+.jqueryFileTree LI.ext_fla { background: url(images/flash.png) left top no-repeat; }
+.jqueryFileTree LI.ext_h { background: url(images/code.png) left top no-repeat; }
+.jqueryFileTree LI.ext_htm { background: url(images/html.png) left top no-repeat; }
+.jqueryFileTree LI.ext_html { background: url(images/html.png) left top no-repeat; }
+.jqueryFileTree LI.ext_jar { background: url(images/java.png) left top no-repeat; }
+.jqueryFileTree LI.ext_jpg { background: url(images/picture.png) left top no-repeat; }
+.jqueryFileTree LI.ext_jpeg { background: url(images/picture.png) left top no-repeat; }
+.jqueryFileTree LI.ext_js { background: url(images/script.png) left top no-repeat; }
+.jqueryFileTree LI.ext_lasso { background: url(images/code.png) left top no-repeat; }
+.jqueryFileTree LI.ext_log { background: url(images/txt.png) left top no-repeat; }
+.jqueryFileTree LI.ext_m4p { background: url(images/music.png) left top no-repeat; }
+.jqueryFileTree LI.ext_mov { background: url(images/film.png) left top no-repeat; }
+.jqueryFileTree LI.ext_mp3 { background: url(images/music.png) left top no-repeat; }
+.jqueryFileTree LI.ext_mp4 { background: url(images/film.png) left top no-repeat; }
+.jqueryFileTree LI.ext_mpg { background: url(images/film.png) left top no-repeat; }
+.jqueryFileTree LI.ext_mpeg { background: url(images/film.png) left top no-repeat; }
+.jqueryFileTree LI.ext_ogg { background: url(images/music.png) left top no-repeat; }
+.jqueryFileTree LI.ext_pcx { background: url(images/picture.png) left top no-repeat; }
+.jqueryFileTree LI.ext_pdf { background: url(images/pdf.png) left top no-repeat; }
+.jqueryFileTree LI.ext_php { background: url(images/php.png) left top no-repeat; }
+.jqueryFileTree LI.ext_png { background: url(images/picture.png) left top no-repeat; }
+.jqueryFileTree LI.ext_ppt { background: url(images/ppt.png) left top no-repeat; }
+.jqueryFileTree LI.ext_psd { background: url(images/psd.png) left top no-repeat; }
+.jqueryFileTree LI.ext_pl { background: url(images/script.png) left top no-repeat; }
+.jqueryFileTree LI.ext_py { background: url(images/script.png) left top no-repeat; }
+.jqueryFileTree LI.ext_rb { background: url(images/ruby.png) left top no-repeat; }
+.jqueryFileTree LI.ext_rbx { background: url(images/ruby.png) left top no-repeat; }
+.jqueryFileTree LI.ext_rhtml { background: url(images/ruby.png) left top no-repeat; }
+.jqueryFileTree LI.ext_rpm { background: url(images/linux.png) left top no-repeat; }
+.jqueryFileTree LI.ext_ruby { background: url(images/ruby.png) left top no-repeat; }
+.jqueryFileTree LI.ext_sql { background: url(images/db.png) left top no-repeat; }
+.jqueryFileTree LI.ext_swf { background: url(images/flash.png) left top no-repeat; }
+.jqueryFileTree LI.ext_tif { background: url(images/picture.png) left top no-repeat; }
+.jqueryFileTree LI.ext_tiff { background: url(images/picture.png) left top no-repeat; }
+.jqueryFileTree LI.ext_txt { background: url(images/txt.png) left top no-repeat; }
+.jqueryFileTree LI.ext_vb { background: url(images/code.png) left top no-repeat; }
+.jqueryFileTree LI.ext_wav { background: url(images/music.png) left top no-repeat; }
+.jqueryFileTree LI.ext_wmv { background: url(images/film.png) left top no-repeat; }
+.jqueryFileTree LI.ext_xls { background: url(images/xls.png) left top no-repeat; }
+.jqueryFileTree LI.ext_xml { background: url(images/code.png) left top no-repeat; }
+.jqueryFileTree LI.ext_zip { background: url(images/zip.png) left top no-repeat; }
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/prettify.css b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/prettify.css new file mode 100644 index 000000000..400fd7428 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/prettify.css @@ -0,0 +1,52 @@ +/* Pretty printing styles. Used with prettify.js. */ + +/* SPAN elements with the classes below are added by prettyprint. */ +.pln { color: #000 } /* plain text */ + +@media screen { + .str { color: #080 } /* string content */ + .kwd { color: #008 } /* a keyword */ + .com { color: #800 } /* a comment */ + .typ { color: #606 } /* a type name */ + .lit { color: #066 } /* a literal value */ + /* punctuation, lisp open bracket, lisp close bracket */ + .pun, .opn, .clo { color: #660 } + .tag { color: #008 } /* a markup tag name */ + .atn { color: #606 } /* a markup attribute name */ + .atv { color: #080 } /* a markup attribute value */ + .dec, .var { color: #606 } /* a declaration; a variable name */ + .fun { color: red } /* a function name */ +} + +/* Use higher contrast and text-weight for printable form. */ +@media print, projection { + .str { color: #060 } + .kwd { color: #006; font-weight: bold } + .com { color: #600; font-style: italic } + .typ { color: #404; font-weight: bold } + .lit { color: #044 } + .pun, .opn, .clo { color: #440 } + .tag { color: #006; font-weight: bold } + .atn { color: #404 } + .atv { color: #060 } +} + +/* Put a border around prettyprinted code snippets. */ +pre.prettyprint { padding: 2px; border: 1px solid #888 } + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { margin-top: 0; margin-bottom: 0 } /* IE indents via margin-left */ +li.L0, +li.L1, +li.L2, +li.L3, +li.L5, +li.L6, +li.L7, +li.L8 { list-style-type: none } +/* Alternate shading for lines */ +li.L1, +li.L3, +li.L5, +li.L7, +li.L9 { background: #eee } diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/select2-3.2.css b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/select2-3.2.css new file mode 100755 index 000000000..568d3e5c0 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/select2-3.2.css @@ -0,0 +1,524 @@ +/* +Version: 3.2 Timestamp: Mon Sep 10 10:38:04 PDT 2012 +*/ +.select2-container { + position: relative; + display: inline-block; + /* inline-block for ie7 */ + zoom: 1; + *display: inline; + vertical-align: top; +} + +.select2-container, +.select2-drop, +.select2-search, +.select2-search input{ + /* + Force border-box so that % widths fit the parent + container without overlap because of margin/padding. + + More Info : http://www.quirksmode.org/css/box.html + */ + -moz-box-sizing: border-box; /* firefox */ + -ms-box-sizing: border-box; /* ie */ + -webkit-box-sizing: border-box; /* webkit */ + -khtml-box-sizing: border-box; /* konqueror */ + box-sizing: border-box; /* css3 */ +} + +.select2-container .select2-choice { + background-color: #fff; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.5, white)); + background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 50%); + background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 50%); + background-image: -o-linear-gradient(bottom, #eeeeee 0%, #ffffff 50%); + background-image: -ms-linear-gradient(top, #eeeeee 0%, #ffffff 50%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee', endColorstr = '#ffffff', GradientType = 0); + background-image: linear-gradient(top, #eeeeee 0%, #ffffff 50%); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -moz-background-clip: padding; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #aaa; + display: block; + overflow: hidden; + white-space: nowrap; + position: relative; + height: 26px; + line-height: 26px; + padding: 0 0 0 8px; + color: #444; + text-decoration: none; +} + +.select2-container.select2-drop-above .select2-choice +{ + border-bottom-color: #aaa; + -webkit-border-radius:0px 0px 4px 4px; + -moz-border-radius:0px 0px 4px 4px; + border-radius:0px 0px 4px 4px; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.9, white)); + background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 90%); + background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 90%); + background-image: -o-linear-gradient(bottom, #eeeeee 0%, white 90%); + background-image: -ms-linear-gradient(top, #eeeeee 0%,#ffffff 90%); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff',GradientType=0 ); + background-image: linear-gradient(top, #eeeeee 0%,#ffffff 90%); +} + +.select2-container .select2-choice span { + margin-right: 26px; + display: block; + overflow: hidden; + white-space: nowrap; + -o-text-overflow: ellipsis; + -ms-text-overflow: ellipsis; + text-overflow: ellipsis; +} + +.select2-container .select2-choice abbr { + display: block; + position: absolute; + right: 26px; + top: 8px; + width: 12px; + height: 12px; + font-size: 1px; + background: url('images/select2.png') right top no-repeat; + cursor: pointer; + text-decoration: none; + border:0; + outline: 0; +} +.select2-container .select2-choice abbr:hover { + background-position: right -11px; + cursor: pointer; +} + +.select2-drop { + background: #fff; + color: #000; + border: 1px solid #aaa; + border-top: 0; + position: absolute; + top: 100%; + -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15); + -moz-box-shadow: 0 4px 5px rgba(0, 0, 0, .15); + -o-box-shadow: 0 4px 5px rgba(0, 0, 0, .15); + box-shadow: 0 4px 5px rgba(0, 0, 0, .15); + z-index: 9999; + width:100%; + margin-top:-1px; + + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.select2-drop.select2-drop-above { + -webkit-border-radius: 4px 4px 0px 0px; + -moz-border-radius: 4px 4px 0px 0px; + border-radius: 4px 4px 0px 0px; + margin-top:1px; + border-top: 1px solid #aaa; + border-bottom: 0; + + -webkit-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15); + -moz-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15); + -o-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15); + box-shadow: 0 -4px 5px rgba(0, 0, 0, .15); +} + +.select2-container .select2-choice div { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; + -moz-background-clip: padding; + -webkit-background-clip: padding-box; + background-clip: padding-box; + background: #ccc; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee)); + background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%); + background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%); + background-image: -o-linear-gradient(bottom, #ccc 0%, #eee 60%); + background-image: -ms-linear-gradient(top, #cccccc 0%, #eeeeee 60%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#cccccc', endColorstr = '#eeeeee', GradientType = 0); + background-image: linear-gradient(top, #cccccc 0%, #eeeeee 60%); + border-left: 1px solid #aaa; + position: absolute; + right: 0; + top: 0; + display: block; + height: 100%; + width: 18px; +} + +.select2-container .select2-choice div b { + background: url('images/select2.png') no-repeat 0 1px; + display: block; + width: 100%; + height: 100%; +} + +.select2-search { + display: inline-block; + white-space: nowrap; + z-index: 10000; + min-height: 26px; + width: 100%; + margin: 0; + padding-left: 4px; + padding-right: 4px; +} + +.select2-search-hidden { + display: block; + position: absolute; + left: -10000px; +} + +.select2-search input { + background: #fff url('images/select2.png') no-repeat 100% -22px; + background: url('images/select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); + background: url('images/select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); + background: url('images/select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); + background: url('images/select2.png') no-repeat 100% -22px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%); + background: url('images/select2.png') no-repeat 100% -22px, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%); + background: url('images/select2.png') no-repeat 100% -22px, linear-gradient(top, #ffffff 85%, #eeeeee 99%); + padding: 4px 20px 4px 5px; + outline: 0; + border: 1px solid #aaa; + font-family: sans-serif; + font-size: 1em; + width:100%; + margin:0; + height:auto !important; + min-height: 26px; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + border-radius: 0; + -moz-border-radius: 0; + -webkit-border-radius: 0; +} + +.select2-drop.select2-drop-above .select2-search input +{ + margin-top:4px; +} + +.select2-search input.select2-active { + background: #fff url('images/spinner.gif') no-repeat 100%; + background: url('images/spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); + background: url('images/spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); + background: url('images/spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); + background: url('images/spinner.gif') no-repeat 100%, -o-linear-gradient(bottom, white 85%, #eeeeee 99%); + background: url('images/spinner.gif') no-repeat 100%, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%); + background: url('images/spinner.gif') no-repeat 100%, linear-gradient(top, #ffffff 85%, #eeeeee 99%); +} + + +.select2-container-active .select2-choice, +.select2-container-active .select2-choices { + -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3); + -moz-box-shadow : 0 0 5px rgba(0,0,0,.3); + -o-box-shadow : 0 0 5px rgba(0,0,0,.3); + box-shadow : 0 0 5px rgba(0,0,0,.3); + border: 1px solid #5897fb; + outline: none; +} + +.select2-dropdown-open .select2-choice { + border: 1px solid #aaa; + border-bottom-color: transparent; + -webkit-box-shadow: 0 1px 0 #fff inset; + -moz-box-shadow : 0 1px 0 #fff inset; + -o-box-shadow : 0 1px 0 #fff inset; + box-shadow : 0 1px 0 #fff inset; + background-color: #eee; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, white), color-stop(0.5, #eeeeee)); + background-image: -webkit-linear-gradient(center bottom, white 0%, #eeeeee 50%); + background-image: -moz-linear-gradient(center bottom, white 0%, #eeeeee 50%); + background-image: -o-linear-gradient(bottom, white 0%, #eeeeee 50%); + background-image: -ms-linear-gradient(top, #ffffff 0%,#eeeeee 50%); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee',GradientType=0 ); + background-image: linear-gradient(top, #ffffff 0%,#eeeeee 50%); + -webkit-border-bottom-left-radius : 0; + -webkit-border-bottom-right-radius: 0; + -moz-border-radius-bottomleft : 0; + -moz-border-radius-bottomright: 0; + border-bottom-left-radius : 0; + border-bottom-right-radius: 0; +} + +.select2-dropdown-open .select2-choice div { + background: transparent; + border-left: none; +} +.select2-dropdown-open .select2-choice div b { + background-position: -18px 1px; +} + +/* results */ +.select2-results { + margin: 4px 4px 4px 0; + padding: 0 0 0 4px; + position: relative; + overflow-x: hidden; + overflow-y: auto; + max-height: 200px; +} + +.select2-results ul.select2-result-sub { + margin: 0 0 0 0; +} + +.select2-results ul.select2-result-sub > li .select2-result-label { padding-left: 20px } +.select2-results ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 40px } +.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 60px } +.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 80px } +.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 100px } +.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 110px } +.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 120px } + +.select2-results li { + list-style: none; + display: list-item; +} + +.select2-results li.select2-result-with-children > .select2-result-label { + font-weight: bold; +} + +.select2-results .select2-result-label { + padding: 3px 7px 4px; + margin: 0; + cursor: pointer; +} + +.select2-results .select2-highlighted { + background: #3875d7; + color: #fff; +} +.select2-results li em { + background: #feffde; + font-style: normal; +} +.select2-results .select2-highlighted em { + background: transparent; +} +.select2-results .select2-no-results, +.select2-results .select2-searching, +.select2-results .select2-selection-limit { + background: #f4f4f4; + display: list-item; +} + +/* +disabled look for already selected choices in the results dropdown +.select2-results .select2-disabled.select2-highlighted { + color: #666; + background: #f4f4f4; + display: list-item; + cursor: default; +} +.select2-results .select2-disabled { + background: #f4f4f4; + display: list-item; + cursor: default; +} +*/ +.select2-results .select2-disabled { + display: none; +} + +.select2-more-results.select2-active { + background: #f4f4f4 url('images/spinner.gif') no-repeat 100%; +} + +.select2-more-results { + background: #f4f4f4; + display: list-item; +} + +/* disabled styles */ + +.select2-container.select2-container-disabled .select2-choice { + background-color: #f4f4f4; + background-image: none; + border: 1px solid #ddd; + cursor: default; +} + +.select2-container.select2-container-disabled .select2-choice div { + background-color: #f4f4f4; + background-image: none; + border-left: 0; +} + + +/* multiselect */ + +.select2-container-multi .select2-choices { + background-color: #fff; + background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff)); + background-image: -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%); + background-image: -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%); + background-image: -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%); + background-image: -ms-linear-gradient(top, #eeeeee 1%, #ffffff 15%); + background-image: linear-gradient(top, #eeeeee 1%, #ffffff 15%); + border: 1px solid #aaa; + margin: 0; + padding: 0; + cursor: text; + overflow: hidden; + height: auto !important; + height: 1%; + position: relative; +} + +.select2-container-multi .select2-choices { + min-height: 26px; +} + +.select2-container-multi.select2-container-active .select2-choices { + -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3); + -moz-box-shadow : 0 0 5px rgba(0,0,0,.3); + -o-box-shadow : 0 0 5px rgba(0,0,0,.3); + box-shadow : 0 0 5px rgba(0,0,0,.3); + border: 1px solid #5897fb; + outline: none; +} +.select2-container-multi .select2-choices li { + float: left; + list-style: none; +} +.select2-container-multi .select2-choices .select2-search-field { + white-space: nowrap; + margin: 0; + padding: 0; +} + +.select2-container-multi .select2-choices .select2-search-field input { + color: #666; + background: transparent !important; + font-family: sans-serif; + font-size: 100%; + height: 15px; + padding: 5px; + margin: 1px 0; + outline: 0; + border: 0; + -webkit-box-shadow: none; + -moz-box-shadow : none; + -o-box-shadow : none; + box-shadow : none; +} + +.select2-container-multi .select2-choices .select2-search-field input.select2-active { + background: #fff url('images/spinner.gif') no-repeat 100% !important; +} + +.select2-default { + color: #999 !important; +} + +.select2-container-multi .select2-choices .select2-search-choice { + -webkit-border-radius: 3px; + -moz-border-radius : 3px; + border-radius : 3px; + -moz-background-clip : padding; + -webkit-background-clip: padding-box; + background-clip : padding-box; + background-color: #e4e4e4; + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f4f4f4', endColorstr='#eeeeee', GradientType=0 ); + background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee)); + background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); + background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); + background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); + background-image: -ms-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); + background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); + -webkit-box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05); + -moz-box-shadow : 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05); + box-shadow : 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05); + color: #333; + border: 1px solid #aaaaaa; + line-height: 13px; + padding: 3px 5px 3px 18px; + margin: 3px 0 3px 5px; + position: relative; + cursor: default; +} +.select2-container-multi .select2-choices .select2-search-choice span { + cursor: default; +} +.select2-container-multi .select2-choices .select2-search-choice-focus { + background: #d4d4d4; +} + +.select2-search-choice-close { + display: block; + position: absolute; + right: 3px; + top: 4px; + width: 12px; + height: 13px; + font-size: 1px; + background: url('images/select2.png') right top no-repeat; + outline: none; +} + +.select2-container-multi .select2-search-choice-close { + left: 3px; +} + + +.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover { + background-position: right -11px; +} +.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close { + background-position: right -11px; +} + +/* disabled styles */ + +.select2-container-multi.select2-container-disabled .select2-choices{ + background-color: #f4f4f4; + background-image: none; + border: 1px solid #ddd; + cursor: default; +} + +.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice { + background-image: none; + background-color: #f4f4f4; + border: 1px solid #ddd; + padding: 3px 5px 3px 5px; +} + +.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close { + display: none; +} +/* end multiselect */ + +.select2-result-selectable .select2-match, +.select2-result-unselectable .select2-result-selectable .select2-match { text-decoration: underline; } +.select2-result-unselectable .select2-match { text-decoration: none; } + +.select2-offscreen { position: absolute; left: -10000px; } + +/* Retina-ize icons */ + +@media only screen and (-webkit-min-device-pixel-ratio: 1.5) { + .select2-search input, .select2-search-choice-close, .select2-container .select2-choice abbr, .select2-container .select2-choice div b { + background-image: url('images/select2x2.png') !important; + background-repeat: no-repeat !important; + background-size: 60px 40px !important; + } + .select2-search input { + background-position: 100% -21px !important; + } +} diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/favicon.ico b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/favicon.ico Binary files differnew file mode 100644 index 000000000..06714d34a --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/favicon.ico diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/applications-internet-2-32-32.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/applications-internet-2-32-32.png Binary files differnew file mode 100644 index 000000000..096e84895 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/applications-internet-2-32-32.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/applications-internet-32-32.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/applications-internet-32-32.png Binary files differnew file mode 100644 index 000000000..096e84895 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/applications-internet-32-32.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/atom.gif b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/atom.gif Binary files differnew file mode 100644 index 000000000..b0e4adf1d --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/atom.gif diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/dialog-error-22-22.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/dialog-error-22-22.png Binary files differnew file mode 100644 index 000000000..7d6aaf6f2 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/dialog-error-22-22.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/dialog-error.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/dialog-error.png Binary files differnew file mode 100644 index 000000000..3bbbb4a0d --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/dialog-error.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/drive-removable-media-16-16.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/drive-removable-media-16-16.png Binary files differnew file mode 100644 index 000000000..915389828 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/drive-removable-media-16-16.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/edit-cut.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/edit-cut.png Binary files differnew file mode 100644 index 000000000..dc9eb9a7a --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/edit-cut.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/folder-saved-search.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/folder-saved-search.png Binary files differnew file mode 100644 index 000000000..ca24a3676 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/folder-saved-search.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/folder.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/folder.png Binary files differnew file mode 100644 index 000000000..65bd0bbdc --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/folder.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/go-home.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/go-home.png Binary files differnew file mode 100644 index 000000000..a46fb2220 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/go-home.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/green-22-22.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/green-22-22.png Binary files differnew file mode 100644 index 000000000..21d46595c --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/green-22-22.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/internet-web-browser-32-32.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/internet-web-browser-32-32.png Binary files differnew file mode 100644 index 000000000..10d2ed4f4 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/internet-web-browser-32-32.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/internet-web-browser.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/internet-web-browser.png Binary files differnew file mode 100644 index 000000000..ac5957ad6 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/internet-web-browser.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/list-add-22-22.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/list-add-22-22.png Binary files differnew file mode 100644 index 000000000..306d3d892 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/list-add-22-22.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/list-add.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/list-add.png Binary files differnew file mode 100644 index 000000000..1aa7f095c --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/list-add.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/medium-spinner.gif b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/medium-spinner.gif Binary files differnew file mode 100644 index 000000000..1c72ebb55 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/medium-spinner.gif diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/package-x-generic.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/package-x-generic.png Binary files differnew file mode 100644 index 000000000..901542615 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/package-x-generic.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/preferences-system-network-proxy-32-32.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/preferences-system-network-proxy-32-32.png Binary files differnew file mode 100644 index 000000000..e75f6f769 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/preferences-system-network-proxy-32-32.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/red-22-22.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/red-22-22.png Binary files differnew file mode 100644 index 000000000..d5202f7fa --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/red-22-22.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/small-spinner.gif b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/small-spinner.gif Binary files differnew file mode 100644 index 000000000..529e72f45 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/small-spinner.gif diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/system-file-manager-32-32.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/system-file-manager-32-32.png Binary files differnew file mode 100644 index 000000000..1d6ce3151 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/system-file-manager-32-32.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/system-lock-screen-22-22.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/system-lock-screen-22-22.png Binary files differnew file mode 100644 index 000000000..dc6b825b1 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/system-lock-screen-22-22.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/system-lock-screen.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/system-lock-screen.png Binary files differnew file mode 100644 index 000000000..f7ea0cd22 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/system-lock-screen.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/system-search-16-16.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/system-search-16-16.png Binary files differnew file mode 100644 index 000000000..fd7f0b07a --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/system-search-16-16.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/system-software-update-32-32.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/system-software-update-32-32.png Binary files differnew file mode 100644 index 000000000..470b5d46f --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/system-software-update-32-32.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/system-users-32-32.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/system-users-32-32.png Binary files differnew file mode 100644 index 000000000..749c825e0 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/system-users-32-32.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/trash.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/trash.png Binary files differnew file mode 100644 index 000000000..0e0953c73 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/trash.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/user-trash-full.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/user-trash-full.png Binary files differnew file mode 100644 index 000000000..695d215a7 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/user-trash-full.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/user-trash.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/user-trash.png Binary files differnew file mode 100644 index 000000000..0e0953c73 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/user-trash.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/utilities-system-monitor-22-22.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/utilities-system-monitor-22-22.png Binary files differnew file mode 100644 index 000000000..f2d266f79 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/utilities-system-monitor-22-22.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/utilities-system-monitor.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/utilities-system-monitor.png Binary files differnew file mode 100644 index 000000000..8734e777a --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/utilities-system-monitor.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/view-refresh-22-22.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/view-refresh-22-22.png Binary files differnew file mode 100644 index 000000000..cab4d02c7 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/view-refresh-22-22.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/view-refresh.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/view-refresh.png Binary files differnew file mode 100644 index 000000000..3fd71d6e5 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/view-refresh.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/weather-clear-22-22.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/weather-clear-22-22.png Binary files differnew file mode 100644 index 000000000..e17ca7ce0 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/weather-clear-22-22.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/weather-clear.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/weather-clear.png Binary files differnew file mode 100644 index 000000000..7dc15ea96 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/images/weather-clear.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/img/glyphicons-halflings-white.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/img/glyphicons-halflings-white.png Binary files differnew file mode 100644 index 000000000..3bf6484a2 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/img/glyphicons-halflings-white.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/img/glyphicons-halflings.png b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/img/glyphicons-halflings.png Binary files differnew file mode 100644 index 000000000..a99699932 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/img/glyphicons-halflings.png diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/img/loading.gif b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/img/loading.gif Binary files differnew file mode 100644 index 000000000..90f28cbdb --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/img/loading.gif diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/img/progressbar.gif b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/img/progressbar.gif Binary files differnew file mode 100644 index 000000000..fbcce6bc9 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/img/progressbar.gif diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/index.html b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/index.html new file mode 100644 index 000000000..761ea3dfd --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/index.html @@ -0,0 +1,79 @@ +<!DOCTYPE html> + +<!-- +~ ~ Licensed to the Apache Software Foundation (ASF) under one +~ ~ or more contributor license agreements. See the NOTICE file +~ ~ distributed with this work for additional information +~ ~ regarding copyright ownership. The ASF licenses this file +~ ~ to you under the Apache License, Version 2.0 (the +~ ~ "License"); you may not use this file except in compliance +~ ~ with the License. You may obtain a copy of the License at +~ ~ +~ ~ http://www.apache.org/licenses/LICENSE-2.0 +~ ~ +~ ~ Unless required by applicable law or agreed to in writing, +~ ~ software distributed under the License is distributed on an +~ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +~ ~ KIND, either express or implied. See the License for the +~ ~ specific language governing permissions and limitations +~ ~ under the License. +~ --> + +<html> +<head> + + <link rel="stylesheet" href="css/jquery.fileupload-ui.css"/> + <link rel="stylesheet" href="css/jqueryFileTree.css"/> + <link rel="stylesheet" href="css/jquery-ui-1.9.2.custom.min.css"/> + <link rel="stylesheet" href="css/select2-3.2.css"/> + <link rel="stylesheet" href="css/bootstrap.2.2.1.css"> + <link rel="stylesheet" href="css/archiva.css"> + <link rel="shortcut icon" href="favicon.ico"/> + <link rel="stylesheet" href="css/prettify.css"/> + + <script type="text/javascript" src="js/jquery-1.8.3.min.js"></script> + <script type="text/javascript" src="js/jquery-ui-1.9.2.custom.min.js"></script> + <script type="text/javascript" src="js/sammy.0.7.1.js"></script> + <script type="text/javascript" data-main="js/archiva/archiva.js" src="js/require.2.1.2.js"></script> + + <title>Apache Archiva</title> + +</head> + +<body id="body_content" style="padding-top: 42px;"> + +<div id="topbar-menu-container"></div> + +<div class="container-fluid" style="min-height: 550px"> + <div class="row-fluid"> + <div class="span2 columns"> + <div class="well sidebar-nav" id="sidebar-content"></div> + </div> + <div class="span10 columns"> + <div class="content"> + <div id="user-messages"></div> + <div id="main-content"></div> + </div> + </div> + </div> + +</div> + +<footer id="footer-content" style="vertical-align: bottom"> +</footer> + +<div id="html-fragments"></div> + +<div id="loadingDiv"> + <div class="loading-indicator"> + <img src="images/medium-spinner.gif" alt="Archiva loading"/> + <span id="loading-msg">Loading</span> + </div> +</div> +<noscript> +Archiva needs Javascript, please check the Javascript configuration of your browser +</noscript> +</body> + + +</html> diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/archiva.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/archiva.js new file mode 100644 index 000000000..6c3bd992a --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/archiva.js @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +appendArchivaVersion=function(){ + return "_archivaVersion="+window.archivaRuntimeInfo.version; +}; + +timestampNoCache=function(){ + if (window.archivaRuntimeInfo.version.match("SNAPSHOT$")){ + return "&archivaTimestamp="+window.archivaRuntimeInfo.timestamp+(window.archivaRuntimeInfo.devMode?"&_="+jQuery.now():""); + } + return ""; +}; + +appendTemplateUrl=function(){ + return appendArchivaVersion()+timestampNoCache(); +}; + +appendJsNoCacheUrl=function(){ + return appendArchivaVersion()+timestampNoCache(); +}; + +$.ajax({ + url: "restServices/archivaUiServices/runtimeInfoService/archivaRuntimeInfo/en", + dataType: 'json', + cache: false, + success:function(data){ + + window.archivaDevMode=data.devMode; + window.archivaJavascriptLog=data.javascriptLog; + window.archivaRuntimeInfo=data; + + requirejs.config({ + baseUrl: "js/", + urlArgs: ""+appendJsNoCacheUrl(), + shim: { + 'sammy':['jquery','jquery.tmpl'], + 'archiva.main':['jquery','jquery.ui','sammy','jquery.tmpl','utils','i18n'], + 'utils':['jquery','jquery.tmpl','i18n'], + 'archiva.templates': ['jquery','jquery.tmpl','utils'], + 'redback.templates': ['jquery','jquery.tmpl','utils'] + }, + paths: { + "i18n":"jquery.i18n.properties-1.0.9", + "jquery": "jquery-1.8.3.min", + "jquery.tmpl": "jquery.tmpl", + "utils": "archiva/utils", + "startup": "archiva/startup", + "jquery.ui": "jquery-ui-1.9.2.custom.min", + "jquery.ui.widget": "jquery.ui.widget-1.9.2", + "jquery.cookie": "jquery.cookie.1.0.0", + "bootstrap": "bootstrap.2.2.1", + "jquery.validate": "jquery.validate-1.9.0", + "jquery.json": "jquery.json-2.3.min", + "knockout": "knockout-2.2.0.debug", + "knockout.simpleGrid": "knockout.simpleGrid", + "knockout.sortable": "knockout-sortable", + "jquery.iframe.transport": "jquery.iframe-transport-1.4", + "jquery.fileupload": "jquery.fileupload-5.10.0", + "jquery.fileupload.ip":"jquery.fileupload-ip-1.0.6", + "jquery.fileupload.ui":"jquery.fileupload-ui-6.6.3", + "tmpl": "tmpl.min", + "purl": "purl-2.2.1", + "prettify": "prettify", + "sammy": "sammy.0.7.1", + "select2": "select2.min-3.2", + "jqueryFileTree": "jqueryFileTree-1.0.1", + "redback": "redback/redback", + "redback.roles": "redback/roles", + "redback.user": "redback/user", + "redback.users": "redback/users", + "redback.templates": "redback/redback-tmpl", + "archiva.general-admin":"archiva/general-admin", + "archiva.templates": "archiva/main-tmpl", + "archiva.repositories": "archiva/repositories", + "archiva.network-proxies": "archiva/network-proxies", + "archiva.proxy-connectors": "archiva/proxy-connectors", + "archiva.repository-groups": "archiva/repository-groups", + "archiva.artifacts-management": "archiva/artifacts-management", + "archiva.search": "archiva/search", + "archiva.proxy-connectors-rules": "archiva/proxy-connectors-rules", + "archiva.docs": "archiva/docs", + "archiva.main": "archiva/main" + } + }); + + requirejs(['jquery','jquery.tmpl','jquery.ui','i18n','sammy','startup','utils','domReady!','archiva.main','archiva.general-admin'], function () { + loadi18n(function () { + $.ajax({ + url: "restServices/archivaUiServices/runtimeInfoService/archivaRuntimeInfo/"+usedLang(), + dataType: 'json', + success:function(data){ + window.archivaDevMode=data.devMode; + window.archivaJavascriptLog=data.javascriptLog; + window.archivaRuntimeInfo=data; + + window.redbackRuntimeConfiguration=mapRedbackRuntimeConfiguration(data.redbackRuntimeConfiguration); + + $.log("security.rememberme.enabled key value:"+ window.redbackRuntimeConfiguration.findPropertyValue('security.rememberme.enabled')); + + require(['sammy','jquery','i18n','jquery.tmpl','archiva.main','utils','domReady!'],function () { + startArchivaApplication(); + $("#loadingDiv").hide(); + drawQuickSearchAutocomplete(); + }) + } + }) + }); + }) + } +}); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/artifacts-management.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/artifacts-management.js new file mode 100644 index 000000000..9a571355d --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/artifacts-management.js @@ -0,0 +1,124 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +define("archiva.artifacts-management",["jquery","i18n","utils","jquery.tmpl","knockout", + "knockout.simpleGrid","jquery.validate","bootstrap","jquery.fileupload","jquery.fileupload.ui"] + , function(jquery,i18n,utils,jqueryTmpl,ko) { + + ArtifactUpload=function(classifier,pomFile){ + this.classifier=classifier; + this.pomFile=pomFile; + } + + ArtifactUploadViewModel=function(managedRepositories){ + var self=this; + this.managedRepositories=ko.observableArray(managedRepositories); + this.repositoryId=ko.observable(); + this.groupId=ko.observable(); + this.artifactId=ko.observable(); + this.version=ko.observable(); + this.packaging=ko.observable(); + this.generatePom=ko.observable(); + + this.artifactUploads=[]; + + saveArtifacts=function(){ + clearUserMessages(); + if(!$("#main-content" ).find("#fileupload" ).valid()){ + return; + } + if(this.artifactUploads.length<1){ + displayErrorMessage( $.i18n.prop("fileupload.upload.required")); + return; + } + var url="restServices/archivaUiServices/fileUploadService/save/"+this.repositoryId()+"/"+this.groupId()+"/"+this.artifactId(); + url+="/"+this.version()+"/"+this.packaging(); + if (this.generatePom()){ + url+="?generatePom=true"; + } + $.ajax(url, { + type: "GET", + dataType: 'json', + success: function(data) { + displaySuccessMessage($.i18n.prop("fileupload.artifacts.saved")); + self.artifactUploads=[]; + $("#main-content" ).find("#uploaded-files-list" ).empty(); + $.ajax("restServices/archivaUiServices/fileUploadService/clearUploadedFiles", {type: "GET", dataType: 'json'}); + clearForm("#main-content #fileupload"); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + } + } + ); + + } + + } + + displayUploadArtifact=function(){ + screenChange(); + var mainContent=$("#main-content"); + mainContent.html(mediumSpinnerImg()); + + + $.ajax("restServices/archivaUiServices/fileUploadService/clearUploadedFiles", { + type: "GET", + dataType: 'json', + success: function(data) { + mainContent.html($("#file-upload-screen" ).html()); + $.ajax("restServices/archivaServices/browseService/userRepositories", { + type: "GET", + dataType: 'json', + success: function(data) { + var artifactUploadViewModel=new ArtifactUploadViewModel(data); + ko.applyBindings(artifactUploadViewModel,mainContent.find("#file-upload-main" ).get(0)); + var fileUpload=$("#main-content" ).find("#fileupload"); + $("#repositoryId" ).select2(); + var validator = fileUpload.validate({ + showErrors: function(validator, errorMap, errorList) { + customShowError("#main-content #fileupload",validator,errorMap,errorMap); + } + }); + + fileUpload.fileupload({ + submit: function (e, data) { + var $this = $(this); + $this.fileupload('send', data); + artifactUploadViewModel.artifactUploads.push(new ArtifactUpload(data.formData.classifier,data.formData.pomFile)); + return false; + } + } + ); + fileUpload.bind('fileuploadsubmit', function (e, data) { + var pomFile = data.context.find('#pomFile' ).attr("checked"); + var classifier = data.context.find('#classifier' ).val(); + if (!data.formData){ + data.formData={}; + } + data.formData.pomFile = pomFile; + data.formData.classifier = classifier; + }); + } + }); + } + }); + } + +});
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/docs.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/docs.js new file mode 100644 index 000000000..5389cdd42 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/docs.js @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +define("archiva.docs",["jquery","i18n","jquery.tmpl","bootstrap"], function() { + + displayRestDocs=function(){ + $.log("displayRestDocs"); + screenChange(); + $("#main-content" ).html($("#rest_docs").tmpl()); + } + + goToArchivaRestDoc=function(target){ + goToRestDoc(target,"rest-docs/rest-docs-archiva-rest-api"); + } + + goToArchivaRestUiDoc=function(target){ + + goToRestDoc(target,"rest-docs/rest-docs-archiva-ui"); + } + + goToRedbackRestDoc=function(target){ + + goToRestDoc(target,"rest-docs/rest-docs-redback-rest-api"); + } + + goToRestDoc=function(target,rootPath){ + var mainContent = $("#main-content"); + mainContent.find("#rest_docs_content" ).html(mediumSpinnerImg()); + $.ajax({ + url:rootPath+"/"+target, + type:"get", + dataType: "html", + success: function(data){ + mainContent.html($("#rest_docs").tmpl()); + if(target.endsWith(".xsd")){ + mainContent.find("#rest_docs_content" ).html("<code id='xsd_content'></code>"); + mainContent.find("#xsd_content" ).html(data); + } else { + mainContent.find("#rest_docs_content" ).html(data); + } + + prettyPrint(); + } + }); + } + + displayRedbackRestDocs=function(){ + window.sammyArchivaApplication.setLocation("#rest-docs-redback-rest-api/index.html"); + } + + displayArchivaRestUIDocs=function(){ + window.sammyArchivaApplication.setLocation("#rest-docs-archiva-ui/index.html"); + } + + displayArchivaRestDocs=function(){ + window.sammyArchivaApplication.setLocation("#rest-docs-archiva-rest-api/index.html"); + } + + loadRestDocs=function(docType, fullPath){ + $.log("loadRestDocs:"+docType+","+fullPath); + //if (docType=='rest-docs-archiva-rest-api'){ + $.ajax({ + url:fullPath, + type:"get", + dataType: "html", + success: function(data){ + $("#main-content" ).find("#rest_docs_content" ).html(data); + prettyPrint(); + } + }); + //} + } + + displayUsersDocs=function(){ + $.log("displayUsersDocs"); + window.open(""); + } + +});
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/general-admin.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/general-admin.js new file mode 100644 index 000000000..0db8054b1 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/general-admin.js @@ -0,0 +1,1585 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +define("archiva.general-admin",["jquery","i18n","utils","jquery.tmpl","knockout","knockout.simpleGrid", + "knockout.sortable","jquery.validate","bootstrap"] + , function(jquery,i18n,utils,jqueryTmpl,ko) { + + //------------------------- + // legacy path part + //------------------------- + + LegacyArtifactPath=function(path,groupId,artifactId,version,classifier,type,update){ + //private String path; + this.path=ko.observable(path); + + /** + * The artifact reference, as " [groupId] : + * [artifactId] : [version] : [classifier] : [type] ". + */ + //private String artifact; + //this.artifact=ko.observable(artifact); + this.update=update; + //private String groupId; + this.groupId=ko.observable(groupId); + + //private String artifactId; + this.artifactId=ko.observable(artifactId); + + //private String version; + this.version=ko.observable(version); + + //private String classifier; + this.classifier=ko.observable(classifier); + + //private String type; + this.type=ko.observable(type); + + this.modified=ko.observable(); + + this.artifact = ko.computed(function() { + var artifactValue=""; + if (this.groupId()){ + artifactValue+=this.groupId(); + } + if (this.artifactId()){ + artifactValue+=":"+this.artifactId(); + } + if (this.version()){ + artifactValue+=":"+this.version(); + } + if (this.classifier()){ + artifactValue+=":"+this.classifier(); + } + if (this.type()){ + artifactValue+=":"+this.type(); + } + return artifactValue; + }, this); + }; + + mapLegacyArtifactPaths=function(data){ + if (data){ + return $.isArray(data)? $.map(data,function(item){ + return mapLegacyArtifactPath(item); + }):[mapLegacyArtifactPath(data)]; + } + return []; + }; + + mapLegacyArtifactPath=function(data){ + return data?new LegacyArtifactPath(data.path,data.groupId,data.artifactId,data.version,data.classifier,data.type):null; + }; + + activateLegacyArtifactPathFormValidation=function(){ + var theForm=$("#main-content" ).find("#legacy-artifact-paths-edit-form"); + var validator = theForm.validate({ + showErrors: function(validator, errorMap, errorList) { + customShowError("#main-content #legacy-artifact-paths-edit-form",validator,errorMap,errorMap); + } + }); + }; + + LegacyArtifactPathViewModel=function(legacyArtifactPath,update,legacyArtifactPathsViewModel){ + var self=this; + this.update=update; + this.legacyArtifactPath=legacyArtifactPath; + this.legacyArtifactPathsViewModel=legacyArtifactPathsViewModel; + + this.display=function(){ + var mainContent=$("#main-content"); + ko.applyBindings(self,mainContent.find("#legacy-artifact-paths-edit" ).get(0)); + mainContent.find("#legacy-artifact-paths-view-tabs-li-edit a").html($.i18n.prop("edit")); + activateLegacyArtifactPathFormValidation(); + activateLegacyArtifactPathsEditTab(); + }; + + displayGrid=function(){ + activateLegacyArtifactPathsGridTab(); + }; + + calculatePath=function(){ + var path=""; + if (self.legacyArtifactPath.groupId()){ + path+=self.legacyArtifactPath.groupId()+"/jars/"; + } + if (self.legacyArtifactPath.artifactId()){ + path+=self.legacyArtifactPath.artifactId(); + } + if (self.legacyArtifactPath.version()){ + path+="-"+self.legacyArtifactPath.version(); + } + if (self.legacyArtifactPath.classifier()){ + path+="-"+self.legacyArtifactPath.classifier(); + } + if (self.legacyArtifactPath.type()){ + path+="."+self.legacyArtifactPath.type(); + } + self.legacyArtifactPath.path(path); + }; + + this.save=function(){ + var theForm=$("#main-content" ).find("#legacy-artifact-paths-edit-form"); + if (!theForm.valid()){ + return; + } + // do that on server side + /*if (theForm.find("#artifact" ).val() + !=theForm.find("#path" ).val()){ + var errorList=[{ + message: $.i18n.prop("path must match artifact"), + element: theForm.find("#path" ).get(0) + }]; + customShowError("#main-content #legacy-artifact-paths-edit-form", null, null, errorList); + return; + }*/ + // TODO call id exists if add ? + clearUserMessages(); + $.log("save ok"); + if (self.update){ + $.log("update"); + }else { + $.ajax("restServices/archivaServices/archivaAdministrationService/addLegacyArtifactPath", + { + type: "POST", + contentType: 'application/json', + data: ko.toJSON(self.legacyArtifactPath), + dataType: 'json', + success: function(data) { + self.legacyArtifactPath.modified(false); + self.legacyArtifactPathsViewModel.legacyArtifactPaths.push(self.legacyArtifactPath); + displaySuccessMessage($.i18n.prop('legacy-artifact-path.added',self.legacyArtifactPath.path())); + activateLegacyArtifactPathsGridTab(); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + } + } + ); + } + } + }; + + LegacyArtifactPathsViewModel=function(){ + var self=this; + this.legacyArtifactPaths=ko.observableArray([]); + + this.gridViewModel = new ko.simpleGrid.viewModel({ + data: self.legacyArtifactPaths, + columns: [ + { + headerText: $.i18n.prop('legacy-artifact-paths.path'), + rowText: "path" + }, + { + headerText: $.i18n.prop('legacy-artifact-paths.artifact'), + rowText: "artifact" + } + ], + pageSize: 5, + gridUpdateCallBack: function(networkProxy){ + $("#main-content").find("#legacy-artifact-paths-table" ).find("[title]").tooltip(); + } + }); + + + editLegacyArtifactPath=function(legacyArtifactPath){ + var legacyArtifactPathViewModel=new LegacyArtifactPathViewModel(legacyArtifactPath,true); + legacyArtifactPathViewModel.display(); + }; + + removeLegacyArtifactPath=function(legacyArtifactPath){ + + openDialogConfirm( + function(){ + + $.ajax("restServices/archivaServices/archivaAdministrationService/deleteLegacyArtifactPath?path="+encodeURIComponent(legacyArtifactPath.path()), + { + type: "GET", + dataType: 'json', + success: function(data) { + self.legacyArtifactPaths.remove(legacyArtifactPath); + displaySuccessMessage($.i18n.prop('legacy-artifact-path.removed',legacyArtifactPath.path())); + activateLegacyArtifactPathsGridTab(); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + }, + complete: function(){ + closeDialogConfirm(); + } + } + ); + }, $.i18n.prop('ok'), $.i18n.prop('cancel'), $.i18n.prop('legacy-artifact-path.delete.confirm',legacyArtifactPath.path()), + $("#legacy-artifact-path-delete-warning-tmpl" ).tmpl(legacyArtifactPath)); + + }; + + updateLegacyArtifactPath=function(legacyArtifactPath){ + + } + + }; + + displayLegacyArtifactPathSupport=function(){ + screenChange(); + var mainContent=$("#main-content"); + mainContent.html(mediumSpinnerImg()); + + $.ajax("restServices/archivaServices/archivaAdministrationService/getLegacyArtifactPaths", { + type: "GET", + dataType: 'json', + success: function(data){ + mainContent.html($("#legacy-artifact-path-main").tmpl()); + var legacyArtifactPathsViewModel=new LegacyArtifactPathsViewModel(); + var legacyPaths=mapLegacyArtifactPaths(data); + $.log("legacyPaths:"+legacyPaths.length); + legacyArtifactPathsViewModel.legacyArtifactPaths(legacyPaths); + ko.applyBindings(legacyArtifactPathsViewModel,mainContent.find("#legacy-artifact-paths-view" ).get(0)); + + mainContent.find("#legacy-artifact-paths-view-tabs").on('show', function (e) { + if ($(e.target).attr("href")=="#legacy-artifact-paths-edit") { + var viewModel = new LegacyArtifactPathViewModel(new LegacyArtifactPath(),false,legacyArtifactPathsViewModel); + viewModel.display(); + activateLegacyArtifactPathFormValidation(); + clearUserMessages(); + } + if ($(e.target).attr("href")=="#legacy-artifact-paths-view") { + mainContent.find("#legacy-artifact-paths-view-tabs-li-edit a").html($.i18n.prop("add")); + clearUserMessages(); + } + + }); + + + activateLegacyArtifactPathsGridTab(); + } + }); + + + }; + + + activateLegacyArtifactPathsGridTab=function(){ + var mainContent = $("#main-content"); + mainContent.find("#legacy-artifact-paths-view-tabs-li-edit").removeClass("active"); + mainContent.find("#legacy-artifact-paths-edit").removeClass("active"); + + mainContent.find("#legacy-artifact-paths-view-tabs-li-grid").addClass("active"); + mainContent.find("#legacy-artifact-paths-view").addClass("active"); + mainContent.find("#legacy-artifact-paths-view-tabs-li-edit a").html($.i18n.prop("add")); + + }; + + activateLegacyArtifactPathsEditTab=function(){ + var mainContent = $("#main-content"); + mainContent.find("#legacy-artifact-paths-view-tabs-li-grid").removeClass("active"); + mainContent.find("#legacy-artifact-paths-view").removeClass("active"); + + mainContent.find("#legacy-artifact-paths-view-tabs-li-edit").addClass("active"); + mainContent.find("#legacy-artifact-paths-edit").addClass("active"); + }; + + + //--------------------------- + // repository scanning part + //--------------------------- + + FileType=function(id,patterns){ + //private String id; + this.id=ko.observable(id); + + //private List<String> patterns; + this.patterns=ko.observableArray(patterns); + + }; + + mapFileType=function(data){ + return new FileType(data.id,data.patterns); + }; + + mapFileTypes=function(data){ + if (data!=null){ + return $.isArray(data)? $.map(data,function(item){ + return mapFileType(item) + }):[mapFileType(data)]; + } + return []; + }; + + AdminRepositoryConsumer=function(enabled,id,description){ + //private boolean enabled = false; + this.enabled=ko.observable(enabled); + + //private String id; + this.id=ko.observable(id) + + //private String description; + this.description=ko.observable(description); + } + + mapAdminRepositoryConsumer=function(data){ + return new AdminRepositoryConsumer(data.enabled,data.id,data.description); + } + + mapAdminRepositoryConsumers=function(data){ + if (data!=null){ + return $.isArray(data)? $.map(data,function(item){ + return mapAdminRepositoryConsumer(item) + }):[mapAdminRepositoryConsumer(data)]; + } + return []; + } + + + + RepositoryScanningViewModel=function(){ + var self=this; + this.fileTypes=ko.observableArray([]); + this.knownAdminRepositoryConsumers=ko.observableArray([]); + this.invalidAdminRepositoryConsumers=ko.observableArray([]); + + this.findFileType=function(id){ + var fileType=null; + for (var i=0;i<self.fileTypes().length;i++){ + if (id==self.fileTypes()[i].id()){ + fileType=self.fileTypes()[i]; + } + } + return fileType; + } + + removeFileTypePattern=function(id,pattern){ + clearUserMessages(); + var url="restServices/archivaServices/archivaAdministrationService/removeFileTypePattern?" + url+="fileTypeId="+encodeURIComponent(id); + url+="&pattern="+encodeURIComponent(pattern); + $.ajax(url, { + type: "GET", + dataType: 'json', + success: function(data){ + self.findFileType(id ).patterns.remove(pattern); + displaySuccessMessage( $.i18n.prop("repository-scanning.file-types.removed.pattern",id,pattern)); + + } + }); + } + + addFileTypePattern=function(id){ + var pattern=$("#main-content #pattern-"+id ).val(); + $.log("addFileTypePattern:"+id+":"+pattern); + clearUserMessages(); + var url="restServices/archivaServices/archivaAdministrationService/addFileTypePattern?" + url+="fileTypeId="+encodeURIComponent(id); + url+="&pattern="+encodeURIComponent(pattern); + $.ajax(url, { + type: "GET", + dataType: 'json', + success: function(data){ + self.findFileType(id ).patterns.push(pattern); + displaySuccessMessage( $.i18n.prop("repository-scanning.file-types.added.pattern",id,pattern)); + + } + }); + } + + disableKnowContentConsumer=function(adminRepositoryConsumer){ + $.log("disableKnowContentConsumer"); + clearUserMessages(); + var userMessages=$("#user-messages" ) + userMessages.html(mediumSpinnerImg()); + var url="restServices/archivaServices/archivaAdministrationService/disabledKnownContentConsumer/" + url+=encodeURIComponent(adminRepositoryConsumer.id()); + $.ajax(url, { + type: "GET", + dataType: 'json', + success: function(data){ + adminRepositoryConsumer.enabled(false); + displaySuccessMessage( $.i18n.prop("repository-scanning.consumers.know.disabled",adminRepositoryConsumer.id())); + removeMediumSpinnerImg(userMessages); + } + }); + } + + enableKnowContentConsumer=function(adminRepositoryConsumer){ + clearUserMessages(); + var userMessages=$("#user-messages" ) + userMessages.html(mediumSpinnerImg()); + var url="restServices/archivaServices/archivaAdministrationService/enabledKnownContentConsumer/" + url+=encodeURIComponent(adminRepositoryConsumer.id()); + $.ajax(url, { + type: "GET", + dataType: 'json', + success: function(data){ + adminRepositoryConsumer.enabled(true); + displaySuccessMessage( $.i18n.prop("repository-scanning.consumers.know.enabled",adminRepositoryConsumer.id())); + removeMediumSpinnerImg(userMessages); + } + }); + } + + disableInvalidContentConsumer=function(adminRepositoryConsumer){ + clearUserMessages(); + var url="restServices/archivaServices/archivaAdministrationService/disabledInvalidContentConsumer/" + url+=encodeURIComponent(adminRepositoryConsumer.id()); + $.ajax(url, { + type: "GET", + dataType: 'json', + success: function(data){ + adminRepositoryConsumer.enabled(false); + displaySuccessMessage( $.i18n.prop("repository-scanning.consumers.invalid.disabled",adminRepositoryConsumer.id())); + } + }); + } + + enableInvalidContentConsumer=function(adminRepositoryConsumer){ + clearUserMessages(); + var url="restServices/archivaServices/archivaAdministrationService/enabledInvalidContentConsumer/" + url+=encodeURIComponent(adminRepositoryConsumer.id()); + $.ajax(url, { + type: "GET", + dataType: 'json', + success: function(data){ + adminRepositoryConsumer.enabled(true); + displaySuccessMessage( $.i18n.prop("repository-scanning.consumers.invalid.enabled",adminRepositoryConsumer.id())); + } + }); + } + + } + + displayRepositoryScanning=function(){ + screenChange(); + var mainContent=$("#main-content"); + + mainContent.html($("#repository-scanning-main").tmpl()); + mainContent.find("#file-types-content").html(mediumSpinnerImg()); + mainContent.find("#consumers-known-content").html(mediumSpinnerImg()); + mainContent.find("#consumers-invalid-content").html(mediumSpinnerImg()); + + var repositoryScanningViewModel=new RepositoryScanningViewModel(); + + $.ajax("restServices/archivaServices/archivaAdministrationService/getFileTypes", { + type: "GET", + dataType: 'json', + success: function(data){ + var fileTypes=mapFileTypes(data); + repositoryScanningViewModel.fileTypes(fileTypes); + ko.applyBindings(repositoryScanningViewModel,mainContent.find("#file-types-content").get(0)); + } + }); + + $.ajax("restServices/archivaServices/archivaAdministrationService/getKnownContentAdminRepositoryConsumers", { + type: "GET", + dataType: 'json', + success: function(data){ + var knownAdminRepositoryConsumers=mapAdminRepositoryConsumers(data); + repositoryScanningViewModel.knownAdminRepositoryConsumers(knownAdminRepositoryConsumers); + ko.applyBindings(repositoryScanningViewModel,mainContent.find("#consumers-known-content").get(0)); + } + }); + + $.ajax("restServices/archivaServices/archivaAdministrationService/getInvalidContentAdminRepositoryConsumers", { + type: "GET", + dataType: 'json', + success: function(data){ + var invalidAdminRepositoryConsumers=mapAdminRepositoryConsumers(data); + repositoryScanningViewModel.invalidAdminRepositoryConsumers(invalidAdminRepositoryConsumers); + ko.applyBindings(repositoryScanningViewModel,mainContent.find("#consumers-invalid-content").get(0)); + } + }); + + } + + //--------------------------- + // network configuration part + //--------------------------- + + NetworkConfiguration=function(maxTotal,maxTotalPerHost,usePooling){ + //private int maxTotal = 30; + this.maxTotal=ko.observable(maxTotal); + + //private int maxTotalPerHost = 30; + this.maxTotalPerHost=ko.observable(maxTotalPerHost); + + //private boolean usePooling = true; + this.usePooling=ko.observable(usePooling); + } + + NetworkConfigurationViewModel=function(networkConfiguration){ + var self=this; + this.networkConfiguration=ko.observable(networkConfiguration); + + save=function(){ + var userMessages=$("#user-messages"); + userMessages.html(mediumSpinnerImg()); + var mainContent=$("#main-content"); + if (!mainContent.find("#network-configuration-edit-form").valid()){ + return; + } + mainContent.find("#network-configuration-btn-save" ).button('loading'); + $.ajax("restServices/archivaServices/archivaAdministrationService/setNetworkConfiguration", { + type: "POST", + contentType: 'application/json', + data: ko.toJSON(self.networkConfiguration), + dataType: 'json', + success: function(data){ + displaySuccessMessage( $.i18n.prop("network-configuration.updated")); + }, + complete: function(){ + removeMediumSpinnerImg(userMessages); + mainContent.find("#network-configuration-btn-save" ).button('reset'); + } + }); + } + } + + displayNetworkConfiguration=function(){ + screenChange(); + var mainContent=$("#main-content"); + mainContent.html(mediumSpinnerImg()); + + $.ajax("restServices/archivaServices/archivaAdministrationService/getNetworkConfiguration", { + type: "GET", + dataType: 'json', + success: function(data){ + mainContent.html($("#network-configuration-screen").tmpl()); + var networkConfiguration=new NetworkConfiguration(data.maxTotal,data.maxTotalPerHost,data.usePooling); + var networkConfigurationViewModel=new NetworkConfigurationViewModel(networkConfiguration); + ko.applyBindings(networkConfigurationViewModel,mainContent.get(0)); + var validator = mainContent.find("#network-configuration-edit-form").validate({ + showErrors: function(validator, errorMap, errorList) { + customShowError(mainContent.find("#network-configuration-edit-form" ).get(0),validator,errorMap,errorMap); + } + }); + } + }); + + } + + //--------------------------- + // UiConfiguration part + //--------------------------- + + displayUiConfiguration=function(){ + screenChange(); + var mainContent=$("#main-content"); + mainContent.html(mediumSpinnerImg()); + $.ajax("restServices/archivaServices/archivaAdministrationService/getUiConfiguration", { + type: "GET", + dataType: 'json', + success: function(data){ + mainContent.html($("#ui-configuration-screen").tmpl()); + var uiConfiguration=new UiConfiguration(data.showFindArtifacts,data.appletFindEnabled,data.disableEasterEggs, + data.applicationUrl,data.disableRegistration); + var uiConfigurationViewModel=new UiConfigurationViewModel(uiConfiguration); + ko.applyBindings(uiConfigurationViewModel,mainContent.get(0)); + } + }); + } + + UiConfiguration=function(showFindArtifacts,appletFindEnabled,disableEasterEggs,applicationUrl,disableRegistration){ + this.showFindArtifacts = ko.observable(showFindArtifacts); + + this.appletFindEnabled = ko.observable(appletFindEnabled); + + this.disableEasterEggs = ko.observable(disableEasterEggs); + + this.applicationUrl = ko.observable(applicationUrl); + + // default to false + this.disableRegistration = ko.observable(disableRegistration?disableRegistration:false); + } + + UiConfigurationViewModel=function(uiConfiguration){ + this.uiConfiguration=ko.observable(uiConfiguration); + var self=this; + save=function(){ + var mainContent=$("#main-content" ); + var userMessages=$("#user-messages"); + userMessages.html( mediumSpinnerImg()); + mainContent.find("#ui-configuration-btn-save" ).button('loading'); + $.ajax("restServices/archivaServices/archivaAdministrationService/setUiConfiguration", { + type: "POST", + contentType: 'application/json', + data: ko.toJSON(self.uiConfiguration), + dataType: 'json', + success: function(data){ + displaySuccessMessage( $.i18n.prop("ui-configuration.updated")); + }, + complete: function(){ + removeMediumSpinnerImg(userMessages); + mainContent.find("#ui-configuration-btn-save" ).button('reset'); + } + }); + } + } + + + //--------------------------- + // System status part + //--------------------------- + + QueueEntry=function(key,entriesNumber){ + this.key=key; + this.entriesNumber=entriesNumber; + } + + + mapQueueEntries=function(data){ + if (data!=null){ + return $.map(data,function(item){ + return new QueueEntry(item.key,item.entriesNumber); + }) + } + return []; + } + + CacheEntry=function(key,size,cacheHits,cacheMiss,cacheHitRate,inMemorySize){ + this.key=key; + this.size=size; + this.cacheHits=cacheHits; + this.cacheMiss=cacheMiss; + this.cacheHitRate=cacheHitRate; + this.inMemorySize=inMemorySize; + } + + mapCacheEntries=function(data){ + if(data!=null){ + return $.map(data,function(item){ + return new CacheEntry(item.key,item.size,item.cacheHits,item.cacheMiss,item.cacheHitRate,item.inMemorySize); + }) + } + return []; + } + + + + displayCacheEntries=function(){ + var divContent = $("#main-content" ).find("#status_caches"); + divContent.html(smallSpinnerImg()); + $.ajax("restServices/archivaServices/systemStatusService/cacheEntries", { + type: "GET", + success: function(data){ + var cacheEntries=mapCacheEntries(data); + divContent.html($("#status_caches_tmpl" ).tmpl({cacheEntries: cacheEntries})); + } + }); + } + + flushCache=function(key){ + clearUserMessages(); + $("#main-content" ).find("#status_caches").html(smallSpinnerImg()); + $.ajax("restServices/archivaServices/systemStatusService/clearCache/"+encodeURIComponent(key), { + type: "GET", + success: function(data){ + displaySuccessMessage( $.i18n.prop("system-status.caches.flushed",key)); + displayCacheEntries(); + } + }); + } + + flushAllCaches=function(){ + clearUserMessages(); + $("#main-content" ).find("#status_caches").html(smallSpinnerImg()); + $.ajax("restServices/archivaServices/systemStatusService/clearAllCaches", { + type: "GET", + success: function(data){ + displaySuccessMessage( $.i18n.prop("system-status.caches.all.flushed")); + displayCacheEntries(); + } + }); + } + + mapRepositoryScannerStatisticsList=function(data){ + if(data!=null){ + return $.isArray(data)? $.map(data,function(item){ + return mapRepositoryScannerStatistics(item); + }):[data]; + } + return []; + } + + + mapRepositoryScannerStatistics=function(data){ + return new RepositoryScannerStatistics(mapManagedRepository(data.managedRepository),data.totalFileCount, + data.newFileCount,data.consumerScanningStatistics); + } + + RepositoryScannerStatistics=function(managedRepository,totalFileCount,newFileCount,consumerScanningStatisticsList){ + //private ManagedRepository managedRepository; + this.managedRepository=managedRepository + + this.consumerScanningStatisticsList= consumerScanningStatisticsList; + + //private long totalFileCount = 0; + this.totalFileCount=totalFileCount; + + //private long newFileCount = 0; + this.newFileCount=newFileCount; + } + + displayScanningStats=function(){ + var divContent = $("#main-content" ).find("#status_scanning"); + divContent.html(smallSpinnerImg()); + $.ajax("restServices/archivaServices/systemStatusService/repositoryScannerStatistics", { + type: "GET", + success: function(data){ + var stats= mapRepositoryScannerStatisticsList(data); + $.log("size:"+data.length); + divContent.html($("#status_scanning_tmpl").tmpl({repositoryScannerStatisticsList:stats})); + } + }); + } + + displayMemoryUsage=function(){ + var divContent = $("#main-content" ).find("#status_memory_info"); + divContent.html(smallSpinnerImg()); + $.ajax("restServices/archivaServices/systemStatusService/memoryStatus", { + type: "GET", + dataType: "text", + success: function(data){ + var memUsage = data; + $.log("memUsage:"+memUsage); + divContent.html(memUsage); + } + }); + } + + displayQueueEntries=function(){ + var divContent = $("#main-content" ).find("#status_queues"); + divContent.html(smallSpinnerImg()); + $.ajax("restServices/archivaServices/systemStatusService/queueEntries", { + type: "GET", + success: function(data){ + var queueEntries=mapQueueEntries(data); + divContent.html($("#status_queues_tmpl" ).tmpl({queueEntries: queueEntries})); + } + }); + } + + displayServerTime=function(){ + var divContent = $("#main-content" ).find("#status_current_time"); + divContent.html(smallSpinnerImg()); + $.ajax("restServices/archivaServices/systemStatusService/currentServerTime/"+encodeURIComponent(usedLang()), { + type: "GET", + dataType: "text", + success: function(data){ + var curTime=data; + $.log("currentServerTime:"+curTime); + divContent.html(curTime); + } + }); + } + + displaySystemStatus=function(){ + screenChange(); + var mainContent=$("#main-content"); + mainContent.html($("#system-status-main").tmpl()); + + var versionInfo=window.archivaRuntimeInfo.version+" - " + +$.i18n.prop('system-status.header.version.buildNumber')+": "+window.archivaRuntimeInfo.buildNumber + +" - "+$.i18n.prop('system-status.header.version.timestampStr')+": "+window.archivaRuntimeInfo.timestampStr; + mainContent.find("#status_version_info").html(versionInfo); + + displayMemoryUsage(); + + displayServerTime(); + + displayQueueEntries(); + + displayScanningStats(); + + displayCacheEntries(); + } + + refreshSystemStatus=function(){ + displayCacheEntries(); + displayScanningStats(); + displayMemoryUsage(); + displayQueueEntries(); + displayServerTime(); + } + + //--------------------------- + // network configuration part + //--------------------------- + OrganisationInformation=function(name,url,logoLocation){ + this.name=ko.observable(name); + this.url=ko.observable(url); + this.logoLocation=ko.observable(logoLocation); + } + mapOrganisationInformation=function(data){ + return new OrganisationInformation(data.name, data.url, data.logoLocation); + } + mapOrganisationInformations=function(data){ + if (data!=null){ + return $.isArray(data)? $.map(data, function(item){ + return mapOrganisationInformation(item); + }):[mapOrganisationInformation(data)]; + } + } + activateOrganisationInformationFormValidation=function(){ + var validate = $("#main-content" ).find("#appearance-configuration-form-id").validate({ + rules: { + name: { + required: true + }, + url: { + required:true, + url:true + }, + logoLocation: { + required:false, + url:true + } + }, + showErrors: function(validator, errorMap, errorList) { + customShowError("#main-content #appearance-configuration-form-id", validator, errorMap, errorMap); + } + }) + } + OrganisationInformationViewModel=function(organisationInformation){ + activateOrganisationInformationFormValidation(); + this.organisationInformation=ko.observable(organisationInformation); + + this.save=function(){ + var mainContent=$("#main-content" ); + if (!mainContent.find("#appearance-configuration-form-id").valid()) { + return; + } + clearUserMessages(); + var userMessages=$("#user-messages"); + userMessages.html(mediumSpinnerImg()); + mainContent.find("#appearance-configuration-btn-save" ).button('loading'); + $.ajax("restServices/archivaServices/archivaAdministrationService/setOrganisationInformation", { + type: "POST", + contentType: "application/json", + data: ko.toJSON(this.organisationInformation), + dataType: "json", + success: function(data){ + displaySuccessMessage($.i18n.prop('appearance-configuration.updated')); + updateAppearanceToolBar(); + }, + error: function(data){ + displayErrorMessage($.i18n.prop('appearance-configuration.updating-error')); + }, + complete: function(){ + removeMediumSpinnerImg(userMessages); + mainContent.find("#appearance-configuration-btn-save" ).button('reset'); + } + }); + } + } + displayAppearanceConfiguration=function(){ + screenChange(); + var mainContent=$("#main-content"); + mainContent.html(mediumSpinnerImg()); + + $.ajax("restServices/archivaServices/archivaAdministrationService/getOrganisationInformation", { + type: "GET", + dataType: 'json', + success: function(data) { + mainContent.html($("#changeAppearance").tmpl()); + var organisationInformation=new OrganisationInformation(data.name,data.url,data.logoLocation); + var organisationInformationViewModel=new OrganisationInformationViewModel(organisationInformation); + ko.applyBindings(organisationInformationViewModel, mainContent.get(0)); + var validator = $("#main-content" ).find("#appearance-configuration-form-id").validate({ + showErrors: function(validator,errorMap,errorList) { + customShowError(mainContent.find("#appearance-configuration-form-id").get(0),validator,errorMap,errorMap); + } + }); + } + }); + } + + //--------------------------- + // report configuration page + //--------------------------- + StatisticsReportRequest=function() { + this.repositories = ko.observableArray( [] ); + this.rowCount = ko.observable(100); + this.startDate = ko.observable(); + this.endDate = ko.observable(); + } + + reportStatisticsFormValidator=function(){ + $.log("reportStatisticsFormValidator"); + var validate = $("#main-content" ).find("#report-statistics-form-id").validate({ + rules: { + rowCountStatistics: { + required:true, + number: true, + min: 10 + }, + startDate: { + date: true + }, + endDate: { + date: true + } + }, + showErrors: function(validator, errorMap, errorList) { + $.log("showErrors"); + customShowError("#main-content #report-statistics-form-id", validator, errorMap, errorMap); + } + }) + } + ReportStatisticsViewModel=function(repositoriesAvailable){ + var mainContent=$("#main-content"); + reportStatisticsFormValidator(); + + var self=this; + this.availableRepositories = ko.observableArray( repositoriesAvailable ); + this.statisticsReport = ko.observable( new StatisticsReportRequest() ); + + mainContent.find("#startDate" ).datepicker(); + mainContent.find("#endDate" ).datepicker(); + mainContent.find("#rowcount-info-button" ).popover(); + + this.showStatistics=function() { + $.log("showStatistics"); + clearUserMessages( "repositoriesErrorMessage" ); + if (!mainContent.find("#report-statistics-form-id").valid()) { + return; + } + if(this.statisticsReport().repositories().length==0){ + displayErrorMessage( $.i18n.prop('report.statistics.repositories.required'), "repositoriesErrorMessage" ); + return; + } + + var resultTabContent = mainContent.find("#report-result"); + + url = "restServices/archivaServices/reportServices/getStatisticsReport/?rowCount=" + + this.statisticsReport().rowCount(); + + for(var i=0;i<this.statisticsReport().repositories().length;i++){ + url += "&repository=" + this.statisticsReport().repositories()[i]; + } + + if(this.statisticsReport().startDate()!=null){ + url += "&startDate=" + this.statisticsReport().startDate(); + } + if(this.statisticsReport().endDate()!=null){ + url += "&endDate=" + this.statisticsReport().endDate(); + } + + $.ajax(url, { + type: "GET", + contentType: 'application/json', + dataType: 'json', + success: function(data){ + resultTabContent.html( $( "#report-statistics" ).tmpl() ); + var reportStatistics = new ReportStatisticsResultViewModel( data ); + ko.applyBindings( reportStatistics, resultTabContent.get( 0 ) ); + var reportResultTabLi=$( "#report-result-tab-li"); + reportResultTabLi.removeClass( "hide" ); + reportResultTabLi.addClass( "active" ); + $( "#report-stat-tab-li" ).removeClass( "active" ); + $( "#report-stat-tab-content" ).removeClass( "active" ); + resultTabContent.addClass( "active" ); + }, + error: function(data){ + var res = $.parseJSON(data.responseText); + displayErrorMessage($.i18n.prop(res.errorMessage)); + } + }); + } + } + ReportStatisticsResultViewModel=function(report){ + this.reports = ko.observableArray( report ); + var self = this; + + this.tableReportViewModel = new ko.simpleGrid.viewModel({ + data: this.reports, + viewModel: this, + columns: [ + { headerText: "Repository ID", rowText: "repositoryId" }, + { headerText: "Start Date", rowText: function(item){return new Date(item.scanStartTime);}}, + { headerText: "Total File Count", rowText: "totalFileCount" }, + { headerText: "Total Size", rowText: "totalArtifactFileSize" }, + { headerText: "Artifact Count", rowText: "totalArtifactCount" }, + { headerText: "Group Count", rowText: "totalGroupCount" }, + { headerText: "Project Count", rowText: "totalProjectCount" }, + { headerText: "Archetypes", rowText: function (item) { return item.totalCountForType.pom === "" ? item.totalCountForType.pom : "0"} }, + { headerText: "Jars", rowText: function (item) { return item.totalCountForType.jar === "" ? item.totalCountForType.jar : "0" } }, + { headerText: "Wars", rowText: function (item) { return item.totalCountForType.war === "" ? item.totalCountForType.war : "0" } }, + { headerText: "Ears", rowText: function (item) { return item.totalCountForType.ear === "" ? item.totalCountForType.ear : "0" } }, + { headerText: "Exes", rowText: function (item) { return item.totalCountForType.exe === "" ? item.totalCountForType.exe : "0" } }, + { headerText: "Dlls", rowText: function (item) { return item.totalCountForType.dll === "" ? item.totalCountForType.dll : "0" } }, + { headerText: "Zips", rowText: function (item) { return item.totalCountForType.zip === "" ? item.totalCountForType.zip : "0" } } + ], + pageSize: 10 + }); + } + + HealthReportRequest=function(){ + this.repositoryId = ko.observable(); + this.rowCount = ko.observable(100); + this.groupId = ko.observable(); + } + HealthReportResult=function(repositoryId,namespace,project,version,id,message,problem,name,facetId){ + this.repositoryId = repositoryId; + this.namespace = namespace; + this.project = project; + this.version = version; + this.id = id; + this.message = message; + this.problem = problem; + this.name = name; + this.facetId = facetId; + } + mapHealthReportResult=function(data){ + if(data==null) return; + return new HealthReportResult( data.repositoryId, data.namespace, data.project, data.version, data.id, data.message, + data.problem, data.name, data.facetId ); + } + mapHealthReportResults=function(data){ + if (data != null) + { + return $.isArray(data)? $.map(data, function(item){ + return mapHealthReportResult(item); + }):[mapHealthReportResult(data)]; + } + return []; + } + ReportHealthResultViewModel=function(report){ + this.reports = ko.observableArray( report ); + var self = this; + this.tableReportViewModel = new ko.simpleGrid.viewModel({ + data: this.reports, + viewModel: this, + columns: [ + { headerText: "ID", rowText: "id" }, + { headerText: "Namespace", rowText: "namespace" }, + { headerText: "Project", rowText: "project" }, + { headerText: "Version", rowText: "version" }, + { headerText: "Name", rowText: "name" }, + { headerText: "Problem", rowText: "problem" }, + { headerText: "Message", rowText: "message" } + ], + pageSize: 10 + }); + } + + reportHealthFormValidator=function(){ + var validate = $("#main-content" ).find("#report-health-form-id").validate({ + rules: { + rowCountHealth: { + required: true, + number: true, + min: 10 + }, + repositoryId: { + required: true + } + }, + showErrors: function(validator, errorMap, errorList) { + customShowError("#main-content #report-health-form-id", validator, errorMap, errorMap); + } + }) + } + ReportHealthViewModel=function(){ + reportHealthFormValidator(); + this.healthReport = ko.observable(new HealthReportRequest()); + + this.showHealth=function() { + if (!$("#main-content" ).find("#report-health-form-id").valid()) { + return; + } + + var resultTabContent = $("#main-content" ).find("#report-result"); + + var url = + "restServices/archivaServices/reportServices/getHealthReports/" + this.healthReport().repositoryId() + "/" + + this.healthReport().rowCount(); + + if (this.healthReport().groupId()) + { + url += "?groupId=" + this.healthReport().groupId(); + } + + $.ajax(url, { + type: "GET", + contentType: 'application/json', + dataType: 'json', + success: function(data){ + var reports = new ReportHealthResultViewModel( mapHealthReportResults( data ) ); + resultTabContent.html( $( "#report-health" ).tmpl() ); + ko.applyBindings( reports, resultTabContent.get( 0 ) ); + var reportResultTabLi=$( "#report-result-tab-li" ); + reportResultTabLi.removeClass( "hide" ); + reportResultTabLi.addClass( "active" ); + $( "#report-health-tab-li" ).removeClass( "active" ); + $( "#report-health-tab-content" ).removeClass( "active" ); + resultTabContent.addClass( "active" ); + }, + error: function(data){ + var res = $.parseJSON(data.responseText); + displayRestError(res); + } + }); + } + } + + displayReportsPage=function(){ + screenChange(); + clearUserMessages(); + var mainContent = $("#main-content"); + mainContent.html(mediumSpinnerImg()); + $.ajax("restServices/archivaServices/searchService/observableRepoIds", { + type: "GET", + dataType: 'json', + success: function(data) { + var repos = mapStringList( data ); + mainContent.html( $( "#report-base" ).tmpl( {repositoriesList:repos} ) ); + var statisticsReportViewModel = ReportStatisticsViewModel( repos ); + var healthReportViewModel = ReportHealthViewModel( ); + ko.applyBindings( statisticsReportViewModel, mainContent.get( 0 ) ); + ko.applyBindings( healthReportViewModel, mainContent.get( 0 ) ); + } + }); + } + + + RedbackRuntimeConfiguration=function(userManagerImpls,ldapConfiguration,migratedFromRedbackConfiguration,configurationPropertiesEntries + ,useUsersCache,cacheConfiguration){ + $.log("new RedbackRuntimeConfiguration"); + var self=this; + this.modified=ko.observable(false); + this.modified.subscribe(function(newValue){$.log("RedbackRuntimeConfiguration modified")}); + + this.userManagerImpls=ko.observableArray(userManagerImpls); + this.userManagerImpls.subscribe(function(newValue){self.modified(true)}); + + this.ldapConfiguration=ko.observable(ldapConfiguration); + this.ldapConfiguration.subscribe(function(newValue){self.modified(true)}); + + this.migratedFromRedbackConfiguration=ko.observable(migratedFromRedbackConfiguration); + + $.log("new RedbackRuntimeConfiguration before configurationPropertiesEntries mapping:"); + + this.configurationPropertiesEntries=ko.observableArray(configurationPropertiesEntries?configurationPropertiesEntries:[]); + this.configurationPropertiesEntries.subscribe(function(newValue){ + self.modified(true); + $.log("configurationPropertiesEntries modified") + }); + + $.log("new RedbackRuntimeConfiguration before configurationPropertiesEntries mapping done"); + + this.findPropertyValue=function(key){ + for(var i=0;i<self.configurationPropertiesEntries().length;i++){ + if(self.configurationPropertiesEntries()[i].key==key){ + var val = self.configurationPropertiesEntries()[i].value; + $.log("findPropertyValue " + key + "->" + val); + return val; + } + } + } + + this.useUsersCache=ko.observable(useUsersCache); + this.useUsersCache.subscribe(function(newValue){self.modified(true)}); + + this.usersCacheConfiguration=ko.observable(cacheConfiguration); + this.usersCacheConfiguration.subscribe(function(newValue){self.modified(true)}); + + + } + + mapRedbackRuntimeConfiguration=function(data){ + $.log("mapRedbackRuntimeConfiguration"); + var ldapConfiguration=mapLdapConfiguration(data.ldapConfiguration); + $.log("mapLdapConfiguration done for "); + + var redbackRuntimeConfiguration = + new RedbackRuntimeConfiguration(data.userManagerImpls,ldapConfiguration,data.migratedFromRedbackConfiguration,[] + ,data.useUsersCache,mapCacheConfiguration(data.usersCacheConfiguration)); + + $.log("mapRedbackRuntimeConfiguration done"); + var configurationPropertiesEntries = data.configurationPropertiesEntries == null ? []: $.each(data.configurationPropertiesEntries,function(item){ + return new Entry(item.key, item.value,function(newValue){ + redbackRuntimeConfiguration.modified(true); + }); + }); + if (!$.isArray(configurationPropertiesEntries)){ + configurationPropertiesEntries=[]; + } + redbackRuntimeConfiguration.configurationPropertiesEntries(configurationPropertiesEntries); + redbackRuntimeConfiguration.modified(false); + return redbackRuntimeConfiguration; + + } + + LdapConfiguration=function(hostName,port,ssl,baseDn,contextFactory,bindDn,password,authenticationMethod, + extraPropertiesEntries){ + + var self=this; + this.modified=ko.observable(false); + + //private String hostName; + this.hostName=ko.observable(hostName); + this.hostName.subscribe(function(newValue){self.modified(true)}); + + //private String port; + this.port=ko.observable(port); + this.port.subscribe(function(newValue){self.modified(true)}); + + //private boolean ssl = false; + this.ssl=ko.observable(ssl); + this.ssl.subscribe(function(newValue){self.modified(true)}); + + //private String baseDn; + this.baseDn=ko.observable(baseDn); + this.baseDn.subscribe(function(newValue){self.modified(true)}); + + //private String contextFactory; + this.contextFactory=ko.observable(contextFactory); + this.contextFactory.subscribe(function(newValue){self.modified(true)}); + + //private String bindDn; + this.bindDn=ko.observable(bindDn); + this.bindDn.subscribe(function(newValue){self.modified(true)}); + + //private String password; + this.password=ko.observable(password); + this.password.subscribe(function(newValue){self.modified(true)}); + + //private String authenticationMethod; + this.authenticationMethod=ko.observable(authenticationMethod); + this.authenticationMethod.subscribe(function(newValue){self.modified(true)}); + + this.extraPropertiesEntries=ko.observableArray(extraPropertiesEntries); + this.extraPropertiesEntries.subscribe(function(newValue){self.modified(true)}); + } + + mapLdapConfiguration=function(data){ + $.log("mapLdapConfiguration"); + if(data){ + var extraPropertiesEntries = data.extraPropertiesEntries == null ? []: $.each(data.extraPropertiesEntries,function(item){ + return new Entry(item.key, item.value); + }); + if (!$.isArray(extraPropertiesEntries)){ + extraPropertiesEntries=[]; + } + $.log("mapLdapConfiguration done"); + return new LdapConfiguration(data.hostName,data.port,data.ssl,data.baseDn,data.contextFactory,data.bindDn,data.password, + data.authenticationMethod,extraPropertiesEntries); + } + return null; + } + + RedbackRuntimeConfigurationViewModel=function(redbackRuntimeConfiguration,userManagerImplementationInformations){ + var self=this; + this.redbackRuntimeConfiguration=ko.observable(redbackRuntimeConfiguration); + this.userManagerImplementationInformations=ko.observable(userManagerImplementationInformations); + + this.usedUserManagerImpls=ko.observableArray([]); + + self.gridViewModel = new ko.simpleGrid.viewModel({ + data: self.redbackRuntimeConfiguration().configurationPropertiesEntries, + columns: [ + { + headerText: $.i18n.prop('redback.runtime.properties.key.label'), + rowText: "key" + }, + { + headerText: $.i18n.prop('redback.runtime.properties.value.label'), + rowText: "value" + } + ], + pageSize: 10,//self.redbackRuntimeConfiguration().configurationPropertiesEntries.length, + gridUpdateCallBack: function(){ + activatePopoverDoc(); + } + }); + + findUserManagerImplementationInformation=function(id){ + for(var i= 0;i<self.userManagerImplementationInformations().length;i++){ + $.log(id+""+self.userManagerImplementationInformations()[i].beanId); + if(id==self.userManagerImplementationInformations()[i].beanId){ + return self.userManagerImplementationInformations()[i]; + } + } + } + + checkLdapServerConfiguration=function(){ + $.log("checkLdapServerConfiguration"); + clearUserMessages(); + var btn = $("#ldap-configuration-check-server"); + btn.button('loading'); + var userMessages=$("#user-messages"); + userMessages.html(mediumSpinnerImg()); + $.log("checkChangedLdapConfiguration"); + $.ajax("restServices/archivaServices/redbackRuntimeConfigurationService/checkLdapConnection", + { + type: "GET", + success: function(data) { + var message=$.i18n.prop('redback.runtime.ldap.verified'); + displaySuccessMessage(message); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + }, + complete:function(data){ + removeMediumSpinnerImg(userMessages); + btn.button('reset'); + } + } + ); + } + + checkChangedLdapConfiguration=function(){ + clearUserMessages(); + var btn = $("#ldap-configuration-check-modification"); + btn.button('loading'); + var userMessages=$("#user-messages"); + userMessages.html(mediumSpinnerImg()); + $.log("checkChangedLdapConfiguration"); + $.ajax("restServices/archivaServices/redbackRuntimeConfigurationService/checkLdapConnection", + { + type: "POST", + contentType: 'application/json', + data:ko.toJSON(self.redbackRuntimeConfiguration().ldapConfiguration), + dataType: 'json', + success: function(data) { + var message=$.i18n.prop('redback.runtime.ldap.verified'); + displaySuccessMessage(message); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + }, + complete:function(data){ + removeMediumSpinnerImg(userMessages); + btn.button('reset'); + } + } + ); + } + + for(var i= 0;i<redbackRuntimeConfiguration.userManagerImpls().length;i++){ + var id=redbackRuntimeConfiguration.userManagerImpls()[i]; + $.log("id:"+id); + var userManagerImplementationInformation=findUserManagerImplementationInformation(id); + + if(userManagerImplementationInformation!=null){ + this.usedUserManagerImpls.push(userManagerImplementationInformation); + } + } + + isUsedUserManagerImpl=function(userManagerImplementationInformation){ + for(var i=0;i<self.usedUserManagerImpls().length;i++){ + if(self.usedUserManagerImpls()[i].beanId==userManagerImplementationInformation.beanId){ + return true; + } + } + return false; + } + + this.availableUserManagerImpls=ko.observableArray([]); + + for(var i=0;i<self.userManagerImplementationInformations().length;i++){ + if(!isUsedUserManagerImpl(self.userManagerImplementationInformations()[i])){ + self.availableUserManagerImpls.push(self.userManagerImplementationInformations()[i]); + } + + } + + userManagerImplMoved=function(arg){ + $.log("userManagerImplMoved"); + self.redbackRuntimeConfiguration().modified(true); + } + + saveRedbackRuntimeConfiguration=function(){ + var mainContent=$("#main-content"); + var valid = mainContent.find("#redback-runtime-general-form-id").valid(); + if (valid==false) { + return; + } + var useLdap = false; + for(var i=0;i<self.usedUserManagerImpls().length;i++){ + var beanId=self.usedUserManagerImpls()[i].beanId; + $.log("beanId:"+beanId); + if(beanId=='ldap'){ + useLdap=true; + } + } + $.log("useLdap:"+useLdap); + if(useLdap==true) { + valid = mainContent.find("#redback-runtime-ldap-form-id").valid(); + $.log("ldap valid:"+valid); + if (valid==false) { + return; + } + } + + $.log("saveRedbackRuntimeConfiguration"); + var saveButton = mainContent.find("#redback-runtime-configuration-save" ); + saveButton.button('loading'); + clearUserMessages(); + var userMessages=$("#user-messages"); + userMessages.html(mediumSpinnerImg()); + self.redbackRuntimeConfiguration().userManagerImpls=ko.observableArray([]); + + for(var i=0;i<self.usedUserManagerImpls().length;i++){ + var beanId=self.usedUserManagerImpls()[i].beanId; + $.log("beanId:"+beanId); + self.redbackRuntimeConfiguration().userManagerImpls.push(beanId); + } + $.log("rememberme enabled:"+self.redbackRuntimeConfiguration().findPropertyValue("security.rememberme.enabled")); + $.ajax("restServices/archivaServices/redbackRuntimeConfigurationService/redbackRuntimeConfiguration", + { + type: "PUT", + contentType: 'application/json', + data:ko.toJSON(self.redbackRuntimeConfiguration), + dataType: 'json', + success: function(data) { + var message=$.i18n.prop('redback-runtime-configuration.updated'); + displaySuccessMessage(message); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + }, + complete:function(data){ + removeMediumSpinnerImg(userMessages); + saveButton.button('reset'); + self.redbackRuntimeConfiguration().modified(false); + self.redbackRuntimeConfiguration().ldapConfiguration().modified(false); + } + } + ); + + } + } + + UserManagerImplementationInformation=function(beanId,descriptionKey,readOnly){ + this.beanId=beanId; + this.descriptionKey=descriptionKey; + this.description= $.i18n.prop(descriptionKey); + this.readOnly=readOnly; + } + + mapUserManagerImplementationInformations=function(data){ + return $.map(data, function(item) { + return mapUserManagerImplementationInformation(item); + }); + } + + mapUserManagerImplementationInformation=function(data){ + if(data==null){ + return null; + } + return new UserManagerImplementationInformation(data.beanId,data.descriptionKey,data.readOnly); + } + + activateRedbackRuntimeGeneralFormValidation=function(){ + var formSelector=$("#main-content" ).find("#redback-runtime-general-form-id"); + var validator = formSelector.validate({ + rules: { + usersCacheTimeToLiveSeconds : { + digits: true, + min: 1, + required: true + }, + usersCacheTimeToIdleSeconds : { + digits: true, + min: 1, + required: true + } + }, + showErrors: function(validator, errorMap, errorList) { + customShowError(formSelector,validator,errorMap,errorMap); + } + }); + } + + activateLdapConfigurationFormValidation=function(){ + var formSelector=$("#main-content" ).find("#redback-runtime-ldap-form-id"); + var validator = formSelector.validate({ + rules: { + ldapHost : { + digits: true, + min: 1, + required: true + }, + ldapPort : { + digits: true, + min: 1, + required: true + } + }, + showErrors: function(validator, errorMap, errorList) { + customShowError(formSelector,validator,errorMap,errorMap); + } + }); + } + + displayRuntimeConfiguration=function(){ + $.log("displayRuntimeConfiguration"); + var mainContent = $("#main-content"); + mainContent.html(mediumSpinnerImg()); + + $.ajax("restServices/archivaServices/redbackRuntimeConfigurationService/userManagerImplementationInformation", { + type: "GET", + dataType: 'json', + success: function(data) { + var userManagerImplementationInformations=mapUserManagerImplementationInformations(data); + $.ajax("restServices/archivaServices/redbackRuntimeConfigurationService/redbackRuntimeConfiguration", { + type: "GET", + dataType: 'json', + success: function(data) { + // TODO use window.redbackRuntimeConfiguration ? + window.redbackRuntimeConfiguration = mapRedbackRuntimeConfiguration(data); + var redbackRuntimeConfigurationViewModel = + new RedbackRuntimeConfigurationViewModel(window.redbackRuntimeConfiguration,userManagerImplementationInformations); + mainContent.html( $("#redback-runtime-configuration-main" ).tmpl() ); + ko.applyBindings(redbackRuntimeConfigurationViewModel,$("#redback-runtime-configuration-content" ).get(0)); + activateRedbackRuntimeGeneralFormValidation(); + activateLdapConfigurationFormValidation(); + } + }); + + } + }); + + } + + CacheConfiguration=function(timeToIdleSeconds,timeToLiveSeconds){ + var self=this; + this.modified=ko.observable(false); + + this.timeToIdleSeconds=ko.observable(timeToIdleSeconds); + this.timeToIdleSeconds.subscribe(function(newValue){self.modified(true)}); + + this.timeToLiveSeconds=ko.observable(timeToLiveSeconds); + this.timeToLiveSeconds.subscribe(function(newValue){self.modified(true)}); + + } + + mapCacheConfiguration=function(data){ + if(!data){ + return new CacheConfiguration(); + } + return new CacheConfiguration(data.timeToIdleSeconds,data.timeToLiveSeconds); + } + +});
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/main-tmpl.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/main-tmpl.js new file mode 100644 index 000000000..1ca725c7c --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/main-tmpl.js @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +require(['jquery',"jquery.tmpl",'i18n',"utils","text!templates/archiva/menu.html", + "text!templates/archiva/generics.html", + "text!templates/archiva/modal.html", + "text!templates/archiva/repositories.html", + "text!templates/archiva/search.html", + "text!templates/archiva/general-admin.html", + "text!templates/archiva/docs.html"], + function(jquery,jqueryTmpl,i18n,utils,menu,generics,modal,repositories, + search,general_admin,docs) { + loadArchivaTemplate=function(){ + var htmlFragment=$("#html-fragments"); + // template loading + htmlFragment.append(menu); + htmlFragment.append(generics); + $.tmpl( modal ).appendTo(htmlFragment); + $.tmpl( docs ).appendTo(htmlFragment); + htmlFragment.append(repositories); + htmlFragment.append(search); + htmlFragment.append(general_admin); + $.log("main-tmpl.js loaded"); + } + } +);
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/main.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/main.js new file mode 100644 index 000000000..653cb6590 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/main.js @@ -0,0 +1,879 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +define("archiva.main",["jquery","jquery.ui","sammy","jquery.tmpl",'i18n',"jquery.cookie","bootstrap","archiva.search", + "jquery.validate","jquery.json","knockout","redback.templates","archiva.templates", + "redback.roles","redback","archiva.general-admin","archiva.repositories", + "archiva.network-proxies","archiva.proxy-connectors","archiva.repository-groups","archiva.artifacts-management", + "archiva.proxy-connectors-rules","archiva.docs"], +function(jquery,ui,sammy,tmpl,i18n,jqueryCookie,bootstrap,archivaSearch,jqueryValidate,jqueryJson,ko) { + + /** + * reccord a cookie for session with the logged user + * @param user see user.js + */ + reccordLoginCookie=function(user) { + + var path = window.redbackRuntimeConfiguration.findPropertyValue("security.rememberme.path"); + path = path ? path : "/"; + + var domain = window.redbackRuntimeConfiguration.findPropertyValue("security.rememberme.domain"); + var secure = window.redbackRuntimeConfiguration.findPropertyValue("security.rememberme.secure"); + + var expires= Number(window.redbackRuntimeConfiguration.findPropertyValue("security.rememberme.timeout")); + + var userJson=ko.toJSON(user); + + $.log("reccordLoginCookie:expires:"+expires+",path:"+path+",domain:"+domain+",secure:"+secure+",user:"+userJson); + + var options = null; + if (secure == 'true'){ + options = { + expires: expires, + path: path, + domain: domain, + secure: secure + } + }else { + options = { + expires: expires, + path: path, + domain: domain + } + } + + $.cookie('archiva_login', userJson,options); + }; + + getUserFromLoginCookie=function(){ + var cookieContent=$.cookie('archiva_login'); + $.log("archiva_login cookie content:"+cookieContent); + var user = $.parseJSON(cookieContent); + if(!user){ + return null; + } + var kUser = new User(user.username, user.password, user.confirmPassword,user.fullName,user.email,user.permanent,user.validated, + user.timestampAccountCreation,user.timestampLastLogin,user.timestampLastPasswordChange,user.locked, + user.passwordChangeRequired,null,user.readOnly,user.userManagerId) + + kUser.rememberme(user.rememberme); + return kUser; + }; + + + + logout=function(doScreenChange){ + var user = getUserFromLoginCookie(); + if(user){ + user.logged=false; + reccordLoginCookie(user); + } + $("#login-link").show(); + $("#register-link").show(); + $("#logout-link").hide(); + $("#change-password-link").hide(); + // cleanup karmas + window.redbackModel.operatioNames=[]; + hideElementWithKarma(); + $("#main-content").empty(); + $("#user-messages" ).empty(); + $.ajax({ + url: 'restServices/redbackServices/loginService/logout', + complete: function(){ + // go to welcome on logout + window.sammyArchivaApplication.setLocation("#search"); + } + + }); + }; + + + + decorateMenuWithKarma=function(user) { + var username = user.username; + $.log("decorateMenuWithKarma"); + // we can receive an observable user so take if it's a function or not + if ($.isFunction(username)){ + username = user.username(); + } + var url = 'restServices/redbackServices/userService/getCurrentUserOperations'; + $.ajax({ + url: url, + success: function(data){ + var mappedOperations = $.map(data, function(item) { + return mapOperation(item); + }); + window.redbackModel.operatioNames = $.map(mappedOperations, function(item){ + return item.name(); + }); + + $("#topbar-menu-container").find("[redback-permissions]").each(function(element){ + checkElementKarma(this); + }); + $("#sidebar-content").find("[redback-permissions]").each(function(element){ + checkElementKarma(this); + }); + checkUrlParams(); + } + }); + }; + + checkElementKarma=function(element){ + var bindingValue = $(element).attr("redback-permissions"); + $(element).hide(); + var neededKarmas = $(eval(bindingValue)).toArray(); + var karmaOk = false; + $(neededKarmas).each(function(value){ + if ($.inArray(neededKarmas[value],window.redbackModel.operatioNames)>=0) { + karmaOk = true; + } + }); + if (karmaOk == false) { + $(element).hide(); + } else { + $(element).show(); + } + }; + + hideElementWithKarma=function(){ + $("#topbar-menu-container [redback-permissions]").each(function(element){ + $(this).hide(); + }); + + $("#sidebar-content").find("[redback-permissions]").each(function(element){ + $(this).hide(); + }); + $.log("hideElementWithKarma"); + }; + + //------------------------------------// + // Change UI with appearance settings // + //------------------------------------// + updateAppearanceToolBar=function() { + $.ajax("restServices/archivaServices/archivaAdministrationService/registrationDisabled", { + type: "GET", + dataType: 'json', + success: function(data) { + //var disableRegistration=data.disableRegistration; + var topbarMenu=$("#topbar-menu"); + if( data){ + $.log("disableRegistration"); + topbarMenu.find("#register-link" ).hide(); + } + $.ajax("restServices/archivaServices/archivaAdministrationService/getOrganisationInformation", { + type: "GET", + dataType: 'json', + success: function(data) { + var organisationLogo=topbarMenu.find("#organisation-logo"); + if(data.url){ + var url = data.url.startsWith("http://") || data.url.startsWith("https://") ? data.url : "http://"+data.url; + var link="<a href='"+url+"' class='brand'>"; + if (data.logoLocation) { + link+="<img src='"+data.logoLocation+"' style='max-height: 30px'/>"; + } else if (data.name) { + link+=data.name; + } else { + link+="Archiva"; + } + link+="</a>"; + organisationLogo.html(link); + } + if (!data.url && data.name){ + organisationLogo.html("<a href='/' class='brand'>"+data.name+"</a>"); + } + if (!data.url && !data.name){ + organisationLogo.html("<a href='/' class='brand'>Archiva</a>"); + } + }, + error: function() { + organisationLogo.html("<a href='/' class='brand'>Archiva</a>"); + } + }); + }}); + }; + + + MainMenuViewModel=function() { + + var self = this; + this.artifactMenuItems = ko.observableArray([ + { text : $.i18n.prop('menu.artifacts') , id: null}, + { text : $.i18n.prop('menu.artifacts.search') , id: "menu-find-search-a", href: "#search" , func: function(){displaySearch(this)}}, + { text : $.i18n.prop('menu.artifacts.browse') , id: "menu-find-browse-a", href: "#browse" , func: function(){displayBrowse(true)}}, + { text : $.i18n.prop('menu.artifacts.upload') , id: "menu-find-upload-a", href: "#upload" , redback: "{permissions: ['archiva-upload-repository']}", func: function(){displayUploadArtifact(true)}} + ]); + this.administrationMenuItems = ko.observableArray([ + { text : $.i18n.prop('menu.administration') , id: null}, + { text : $.i18n.prop('menu.repository.groups') , id: "menu-repository-groups-list-a" , href: "#repositorygroup" , redback: "{permissions: ['archiva-manage-configuration']}", func: function(){displayRepositoryGroups()}}, + { text : $.i18n.prop('menu.repositories') , id: "menu-repositories-list-a" , href: "#repositorylist" , redback: "{permissions: ['archiva-manage-configuration']}", func: function(){displayRepositoriesGrid()}}, + { text : $.i18n.prop('menu.proxy-connectors') , id: "menu-proxy-connectors-list-a" , href: "#proxyconnectors" , redback: "{permissions: ['archiva-manage-configuration']}", func: function(){displayProxyConnectors()}}, + { text : $.i18n.prop('menu.proxy-connectors-rules') , id: "menu.proxy-connectors-rules-list-a" , href: "#proxyconnectorsrules" , redback: "{permissions: ['archiva-manage-configuration']}", func: function(){displayProxyConnectorsRules()}}, + { text : $.i18n.prop('menu.network-proxies') , id: "menu-network-proxies-list-a" , href: "#networkproxies" , redback: "{permissions: ['archiva-manage-configuration']}", func: function(){displayNetworkProxies()}}, + { text : $.i18n.prop('menu.legacy-artifact-support') , id: "menu-legacy-support-list-a" , href: "#legacy" , redback: "{permissions: ['archiva-manage-configuration']}", func: function(){displayLegacyArtifactPathSupport()}}, + { text : $.i18n.prop('menu.repository-scanning') , id: "menu-repository-scanning-list-a" , href: "#scanningList" , redback: "{permissions: ['archiva-manage-configuration']}", func: function(){displayRepositoryScanning()}}, + { text : $.i18n.prop('menu.network-configuration') , id: "menu-network-configuration-list-a" , href: "#network" , redback: "{permissions: ['archiva-manage-configuration']}", func: function(){displayNetworkConfiguration()}}, + { text : $.i18n.prop('menu.system-status') , id: "menu-system-status-list-a" , href: "#status" , redback: "{permissions: ['archiva-manage-configuration']}", func: function(){displaySystemStatus()}}, + { text : $.i18n.prop('menu.appearance-configuration') , id: "menu-appearance-list-a" , href: "#appearance" , redback: "{permissions: ['archiva-manage-configuration']}", func: function(){displayAppearanceConfiguration()}}, + { text : $.i18n.prop('menu.ui-configuration') , id: "menu-ui-configuration-list-a" , href: "#uiconfig" , redback: "{permissions: ['archiva-manage-configuration']}", func: function(){displayUiConfiguration()}}, + { text : $.i18n.prop('menu.reports') , id: "menu-report-list-a" , href: "#reports" , redback: "{permissions: ['archiva-manage-configuration']}", func: function(){displayReportsPage()}} + ]); + + this.usersMenuItems = ko.observableArray([ + { text : $.i18n.prop('menu.users') , id: null}, + { text : $.i18n.prop('menu.users.manage') , id: "menu-users-list-a", href: "#users" , redback: "{permissions: ['archiva-manage-users']}", func: function(){displayUsersGrid()}}, + { text : $.i18n.prop('menu.users.roles') , id: "menu-roles-list-a", href: "#roles" , redback: "{permissions: ['archiva-manage-users']}", func: function(){displayRolesGrid()}}, + { text : $.i18n.prop('menu.runtime-configuration') , id: "menu-runtime-configuration-list-a" , href: "#runtimeconfig" , redback: "{permissions: ['archiva-manage-configuration']}", func: function(){displayRuntimeConfiguration()}} + ]); + + this.docsMenuItems = ko.observableArray([ + { text : $.i18n.prop('menu.docs') , id: null}, + { text : $.i18n.prop('menu.docs.rest') , id: "menu-docs-rest-list-a", href: "#docs-rest", target: "", func: function(){displayRestDocs()}}, + { text : $.i18n.prop('menu.docs.users') , id: "menu-docs-users-list-a", href: "http://archiva.apache.org/docs/"+window.archivaRuntimeInfo.version, target: "_blank", func: function(){displayUsersDocs()}} + ]); + + this.activeMenuId = ko.observable(); + + window.sammyArchivaApplication = Sammy(function () { + + this.get('#quicksearch~:artifactId',function(){ + self.activeMenuId("search"); + $("#main-content" ).html(mediumSpinnerImg()); + var artifactId= this.params.artifactId; + // user can be in a non search view so init the search view first + var searchViewModel = new SearchViewModel(); + var searchRequest = new SearchRequest(); + searchRequest.artifactId(artifactId); + searchViewModel.searchRequest(searchRequest); + displaySearch(function(){ + searchViewModel.externalAdvancedSearch(); + },searchViewModel); + }); + + this.get('#basicsearch/:queryterms',function(){ + self.activeMenuId("search"); + var queryterms= this.params.queryterms; + $.log("queryterms:"+queryterms); + var searchViewModel = new SearchViewModel(); + var searchRequest = new SearchRequest(); + searchRequest.queryTerms(queryterms); + searchViewModel.searchRequest(searchRequest); + displaySearch(function(){ + searchViewModel.externalBasicSearch(); + },searchViewModel); + + }); + this.get('#basicsearch~:repositoryIds/:queryterms',function(){ + self.activeMenuId("search"); + var queryterms= this.params.queryterms; + var repositoryIds = this.params.repositoryIds; + var repos = repositoryIds.split("~"); + $.log("queryterms:"+queryterms+',repositoryIds:'+repositoryIds+",repos:"+repos.length); + var searchViewModel = new SearchViewModel(); + var searchRequest = new SearchRequest(); + searchRequest.queryTerms(queryterms); + searchRequest.repositories=repos; + searchViewModel.searchRequest(searchRequest); + displaySearch(function(){ + searchViewModel.externalBasicSearch(); + },searchViewModel); + }); + + this.get('#basicsearch~:repositoryIds/:queryterms',function(){ + self.activeMenuId("search"); + var queryterms= this.params.queryterms; + var repositoryIds = this.params.repositoryIds; + var repos = repositoryIds.split("~"); + $.log("queryterms:"+queryterms+',repositoryIds:'+repositoryIds+",repos:"+repos.length); + var searchViewModel = new SearchViewModel(); + var searchRequest = new SearchRequest(); + searchRequest.queryTerms(queryterms); + searchRequest.repositories=repos; + searchViewModel.searchRequest(searchRequest); + displaySearch(function(){ + searchViewModel.externalBasicSearch(); + },searchViewModel); + }); + + this.get('#basicsearch/:queryterms',function(){ + self.activeMenuId("search"); + var queryterms= this.params.queryterms; + $.log("queryterms:"+queryterms); + var searchViewModel = new SearchViewModel(); + var searchRequest = new SearchRequest(); + searchRequest.queryTerms(queryterms); + searchViewModel.searchRequest(searchRequest); + displaySearch(function(){ + searchViewModel.externalBasicSearch(); + },searchViewModel); + }); + + var advancedSearchRoute=function(params){ + self.activeMenuId("search"); + var repositoryIds = params.repositoryIds; + var repos = repositoryIds ? repositoryIds.split("~"):[]; + var queryTerms = params.queryterms; + var terms=queryTerms?queryTerms.split('~'):[]; + $.log("queryTerms:"+queryTerms+",terms.length:"+terms.length); + var groupId= terms.length>0?terms[0]:""; + var artifactId= terms.length>1?terms[1]:""; + var version= terms.length>2?terms[2]:""; + var classifier= terms.length>3?terms[3]:""; + var packaging= terms.length>4?terms[4]:""; + var className= terms.length>5?terms[5]:""; + $.log("groupId:artifactId:version:classifier:packaging:className="+groupId+':'+artifactId+':'+version+':'+classifier+':'+packaging+':'+className); + var searchViewModel = new SearchViewModel(); + var searchRequest = new SearchRequest(); + searchRequest.groupId(groupId); + searchRequest.artifactId(artifactId); + searchRequest.version(version); + searchRequest.classifier(classifier); + searchRequest.packaging(packaging); + searchRequest.className(className); + //searchRequest.repositories=repos; + //searchRequest.selectedRepoIds=repos; + searchViewModel.searchRequest(searchRequest); + displaySearch(function(){ + searchViewModel.search("restServices/archivaServices/searchService/searchArtifacts",repos); + },searchViewModel); + }; + + this.get("#advancedsearch/:queryterms",function(){ + advancedSearchRoute(this.params); + }); + + this.get("#advancedsearch~:repositoryIds/:queryterms",function(){ + advancedSearchRoute(this.params); + }); + + + this.get('#open-admin-create-box',function(){ + $.log("#open-admin-create-box"); + adminCreateBox(); + }); + + // #artifact-(optionnal repositoryId) + // format groupId:artifactId org.apache.maven.plugins:maven-jar-plugin + // or groupId:artifactId:version org.apache.maven.plugins:maven-jar-plugin:2.3.1 + this.get('#artifact/:groupId/:artifactId',function(context){ + var groupId= this.params.groupId; + var artifactId= this.params.artifactId; + $.log("get #artifact:"+groupId+":"+artifactId); + self.activeMenuId("browse"); + goToBrowseArtifactDetail(groupId,artifactId);//,null,null); + }); + this.get('#artifact~:repositoryId/:groupId/:artifactId',function(context){ + var groupId= this.params.groupId; + var artifactId= this.params.artifactId; + var repositoryId = this.params.repositoryId; + self.activeMenuId("browse"); + $.log("get #artifact:"+groupId+":"+artifactId); + goToBrowseArtifactDetail(groupId,artifactId,repositoryId);//,null,null); + }); + + + var checkArtifactDetailContent=function(groupId,artifactId,version,repositoryId,tabToActivate,idContentToCheck,contentDisplayFn,classifier){ + self.activeMenuId("browse"); + // no need to recalculate all stuff just activate the tab + var htmlId = idContentToCheck?idContentToCheck:"browse_artifact_detail"; + // olamy: cause some issues when browsing so desactivate this fix until more check + // navigating from dependencies list or dependency or used by of an artifact to fix in search.js + /* + var htmlIdSelect = $("#main-content").find("#"+htmlId ); + if(htmlIdSelect.html()!=null){ + if( $.trim(htmlIdSelect.html().length)>0){ + $("#main-content #"+tabToActivate).tab('show'); + $.log("checkArtifactDetailContent " + htmlId + " html not empty no calculation, tabToActivate:"+tabToActivate); + return; + } + } + */ + + var artifactAvailableUrl="restServices/archivaServices/browseService/artifactAvailable/"+encodeURIComponent(groupId)+"/"+encodeURIComponent(artifactId); + artifactAvailableUrl+="/"+encodeURIComponent(version); + if(classifier){ + artifactAvailableUrl+="/"+encodeURIComponent(classifier); + } + + var selectedRepo=getSelectedBrowsingRepository(); + if (selectedRepo){ + artifactAvailableUrl+="?repositoryId="+encodeURIComponent(selectedRepo); + } + $("#main-content").html( mediumSpinnerImg()); + $.ajax(artifactAvailableUrl, { + type: "GET", + dataType: 'json', + success: function(data) { + // TODO take of the result true or false + //$.log("artifactAvailable:"+data); + generalDisplayArtifactDetailsVersionView(groupId,artifactId,version,repositoryId, + function(artifactVersionDetailViewModel){ + $("#main-content #"+tabToActivate).tab('show'); + if(contentDisplayFn){ + contentDisplayFn(groupId,artifactId,version,artifactVersionDetailViewModel); + } + } + ); + + } + }); + + + }; + + this.get('#artifact/:groupId/:artifactId/:version',function(context){ + + var repositoryId = this.params.repositoryId; + var groupId= this.params.groupId; + var artifactId= this.params.artifactId; + var version= this.params.version; + checkArtifactDetailContent(groupId,artifactId,version,repositoryId,"artifact-details-info-content-a"); + }); + this.get('#artifact~:repositoryId/:groupId/:artifactId/:version',function(context){ + + var repositoryId = this.params.repositoryId; + var groupId= this.params.groupId; + var artifactId= this.params.artifactId; + var version= this.params.version; + checkArtifactDetailContent(groupId,artifactId,version,repositoryId,"artifact-details-info-content-a"); + }); + + this.get('#artifact/:groupId/:artifactId/:version/:classifier',function(context){ + var groupId= this.params.groupId; + var artifactId= this.params.artifactId; + var version= this.params.version; + var classifier= this.params.classifier; + checkArtifactDetailContent(groupId,artifactId,version,null,"artifact-details-info-content-a",null,null,classifier); + }); + + this.get('#artifact~:repositoryId/:groupId/:artifactId/:version/:classifier',function(context){ + + var repositoryId = this.params.repositoryId; + var groupId= this.params.groupId; + var artifactId= this.params.artifactId; + var version= this.params.version; + var classifier= this.params.classifier; + checkArtifactDetailContent(groupId,artifactId,version,repositoryId,"artifact-details-info-content-a",null,null,classifier); + }); + + this.get('#artifact-dependencies/:groupId/:artifactId/:version',function(context){ + + var repositoryId = this.params.repositoryId; + var groupId= this.params.groupId; + var artifactId= this.params.artifactId; + var version= this.params.version; + + checkArtifactDetailContent(groupId,artifactId,version,repositoryId,"artifact-details-dependencies-content-a"); + + }); + + this.get('#artifact-dependencies/:groupId/:artifactId/:version',function(context){ + + var repositoryId = this.params.repositoryId; + var groupId= this.params.groupId; + var artifactId= this.params.artifactId; + var version= this.params.version; + checkArtifactDetailContent(groupId,artifactId,version,repositoryId,"artifact-details-dependencies-content-a"); + + }); + + this.get('#artifact-dependencies~:repositoryId/:groupId/:artifactId/:version',function(context){ + + var repositoryId = this.params.repositoryId; + var groupId= this.params.groupId; + var artifactId= this.params.artifactId; + var version= this.params.version; + checkArtifactDetailContent(groupId,artifactId,version,repositoryId,"artifact-details-dependencies-content-a"); + }); + + this.get('#artifact-details-download-content/:groupId/:artifactId/:version',function(context){ + + var repositoryId = this.params.repositoryId; + var groupId= this.params.groupId; + var artifactId= this.params.artifactId; + var version= this.params.version; + + checkArtifactDetailContent(groupId,artifactId,version,null,"artifact-details-download-content-a","artifact-details-download-content", + function(groupId,artifactId,version,artifactVersionDetailViewModel){ + displayArtifactDownloadContent(artifactVersionDetailViewModel); + }); + + }); + + this.get('#artifact-details-download-content~:repositoryId/:groupId/:artifactId/:version',function(context){ + + var repositoryId = this.params.repositoryId; + var groupId= this.params.groupId; + var artifactId= this.params.artifactId; + var version= this.params.version; + checkArtifactDetailContent(groupId,artifactId,version,repositoryId,"artifact-details-download-content-a","artifact-details-download-content", + function(groupId,artifactId,version,artifactVersionDetailViewModel){ + displayArtifactDownloadContent(artifactVersionDetailViewModel); + }); + }); + + + this.get('#artifact-dependency-tree/:groupId/:artifactId/:version',function(context){ + + var repositoryId = this.params.repositoryId; + var groupId= this.params.groupId; + var artifactId= this.params.artifactId; + var version= this.params.version; + checkArtifactDetailContent(groupId,artifactId,version,repositoryId,"artifact-details-dependency-tree-content-a"); + }); + + this.get('#artifact-dependency-tree~:repositoryId/:groupId/:artifactId/:version',function(context){ + + var repositoryId = this.params.repositoryId; + var groupId= this.params.groupId; + var artifactId= this.params.artifactId; + var version= this.params.version; + checkArtifactDetailContent(groupId,artifactId,version,repositoryId,"artifact-details-dependency-tree-content-a"); + }); + + this.get('#artifact-mailing-list/:groupId/:artifactId/:version',function(context){ + + var repositoryId = this.params.repositoryId; + var groupId= this.params.groupId; + var artifactId= this.params.artifactId; + var version= this.params.version; + checkArtifactDetailContent(groupId,artifactId,version,repositoryId,"artifact-details-mailing-list-content-a"); + }); + + this.get('#artifact-mailing-list~:repositoryId/:groupId/:artifactId/:version',function(context){ + + var repositoryId = this.params.repositoryId; + var groupId= this.params.groupId; + var artifactId= this.params.artifactId; + var version= this.params.version; + checkArtifactDetailContent(groupId,artifactId,version,repositoryId,"artifact-details-mailing-list-content-a"); + }); + + + var calculateUsedBy=function(groupId,artifactId,version){ + var dependeesContentDiv=$("#main-content" ).find("#artifact-details-used-by-content" ); + var dependeesTable=dependeesContentDiv.find("#artifact-usedby-table"); + + dependeesContentDiv.append(mediumSpinnerImg()); + var dependeesUrl="restServices/archivaServices/browseService/dependees/"+encodeURIComponent(groupId); + dependeesUrl+="/"+encodeURIComponent(artifactId); + dependeesUrl+="/"+encodeURIComponent(version); + var selectedRepo=getSelectedBrowsingRepository(); + if (selectedRepo){ + dependeesUrl+="?repositoryId="+encodeURIComponent(selectedRepo); + } + $.ajax(dependeesUrl, { + type: "GET", + dataType: 'json', + success: function(data) { + var artifacts=mapArtifacts(data); + var gridViewModel = new ko.simpleGrid.viewModel({ + data: artifacts, + columns: [], + pageSize: 7, + gridUpdateCallBack: function(){ + // no op + } + }); + $.log("artifacts:"+artifacts.length); + dependeesTable.attr("data-bind", + "simpleGrid: gridViewModel,simpleGridTemplate:'dependees_tmpl',pageLinksId:'usedbyPagination',data:'artifacts'"); + ko.applyBindings({artifacts:artifacts,gridViewModel:gridViewModel},dependeesContentDiv.get(0)); + }, + complete: function(){ + removeMediumSpinnerImg(dependeesContentDiv); + } + }); + + }; + + this.get('#artifact-used-by/:groupId/:artifactId/:version',function(context){ + + var repositoryId = this.params.repositoryId; + var groupId= this.params.groupId; + var artifactId= this.params.artifactId; + var version= this.params.version; + checkArtifactDetailContent(groupId,artifactId,version,repositoryId,"artifact-details-used-by-content-a","artifact-details-used-by-content",calculateUsedBy); + }); + + this.get('#artifact-used-by~:repositoryId/:groupId/:artifactId/:version',function(context){ + + var repositoryId = this.params.repositoryId; + var groupId= this.params.groupId; + var artifactId= this.params.artifactId; + var version= this.params.version; + checkArtifactDetailContent(groupId,artifactId,version,repositoryId,"artifact-details-used-by-content-a","artifact-details-used-by-content",calculateUsedBy); + }); + + var calculateMetadatas=function(groupId,artifactId,version,artifactVersionDetailViewModel){ + + var metadatasContentDiv=$("#main-content" ).find("#artifact-details-metadatas-content" ); + var metadatasUrl="restServices/archivaServices/browseService/metadatas/"+encodeURIComponent(groupId); + metadatasUrl+="/"+encodeURIComponent(artifactId); + metadatasUrl+="/"+encodeURIComponent(version); + var selectedRepo=getSelectedBrowsingRepository(); + if (selectedRepo){ + metadatasUrl+="?repositoryId="+encodeURIComponent(selectedRepo); + } + + //fixe self.entries not in the scope + + $.ajax(metadatasUrl, { + type: "GET", + dataType: 'json', + success: function(data) { + var entries= $.map(data,function(e,i){ + return new MetadataEntry( e.key, e.value,false); + }); + artifactVersionDetailViewModel.entries(entries); + } + }); + }; + + this.get('#artifact-metadatas/:groupId/:artifactId/:version',function(context){ + + var repositoryId = this.params.repositoryId; + var groupId= this.params.groupId; + var artifactId= this.params.artifactId; + var version= this.params.version; + checkArtifactDetailContent(groupId,artifactId,version,repositoryId,"artifact-details-metadatas-content-a",null,calculateMetadatas); + }); + + this.get('#artifact-metadatas~:repositoryId/:groupId/:artifactId/:version',function(context){ + + var repositoryId = this.params.repositoryId; + var groupId= this.params.groupId; + var artifactId= this.params.artifactId; + var version= this.params.version; + checkArtifactDetailContent(groupId,artifactId,version,repositoryId,"artifact-details-metadatas-content-a",null,calculateMetadatas); + }); + + + this.get('#browse/:groupId',function(context){ + var groupId = this.params.groupId; + if (groupId){ + displayBrowseGroupId(groupId); + } else { + displayBrowse(true); + } + }); + this.get('#browse~:repositoryId/:groupId',function(context){ + var groupId = this.params.groupId; + var repositoryId = this.params.repositoryId; + $.log("repositoryId:"+repositoryId); + if (groupId){ + displayBrowseGroupId(groupId,repositoryId); + } else { + displayBrowse(true,repositoryId); + } + }); + this.get('#browse~:repositoryId',function(context){ + var repositoryId = this.params.repositoryId; + $.log("repositoryId:"+repositoryId); + displayBrowse(true,repositoryId); + }); + + this.get('#welcome', function () { + $.log("#welcome hash"); + checkCreateAdminLink(function(){window.sammyArchivaApplication.setLocation("#search")}); + + }); + + this.get('#:folder', function () { + var folder = this.params.folder; + self.activeMenuId(folder); + var baseItems = self.artifactMenuItems()?self.artifactMenuItems():[]; + ko.utils.arrayFirst(baseItems.concat(self.usersMenuItems(), self.administrationMenuItems(),self.docsMenuItems()), function(p) { + if ( p.href == "#"+self.activeMenuId()) { + screenChange(); + p.func(); + } + }); + }); + + this.get("#rest-docs-archiva-rest-api/:target",function(){ + var target=this.params.target; + $.log("archiva-rest-docs, target:"+target); + goToArchivaRestDoc(target); + }); + + this.get("#rest-docs-archiva-ui/:target",function(){ + var target=this.params.target; + $.log("archiva-rest-docs-ui, target:"+target); + goToArchivaRestUiDoc(target); + }); + + this.get("#rest-docs-redback-rest-api/:target",function(){ + var target=this.params.target; + $.log("redback-rest-docs, target:"+target); + goToRedbackRestDoc(target); + }); + + this.get("#managedrepositoryedit/:repositoryId",function(){ + var repositoryId=this.params.repositoryId; + $.log("edit managed repository:"+repositoryId); + displayRepositoriesGrid(function(managedRepositoriesViewModel){managedRepositoriesViewModel.editManagedRepositoryWithId(repositoryId)}); + }); + + this.get("#repositorygroupedit/:groupId",function(){ + var groupId=this.params.groupId; + $.log("edit repository group:"+groupId); + displayRepositoryGroups(function(repositoryGroupsViewModel){repositoryGroupsViewModel.editRepositoryGroupWithId(groupId)}); + + }); + + + }); + }; + + userLoggedCallbackFn=function(user){ + $.log("userLoggedCallbackFn:"+ (user?user.username():null)); + var loginLink=$("#login-link"); + var registerLink=$("#register-link"); + var changePasswordLink=$("#change-password-link"); + if (!user) { + loginLink.show(); + registerLink.show(); + changePasswordLink.hide(); + checkUrlParams(); + } else { + changePasswordLink.show(); + $("#logout-link").show(); + registerLink.hide(); + loginLink.hide(); + decorateMenuWithKarma(user); + } + }; + + checkSecurityLinks=function(){ + userLogged(userLoggedCallbackFn); + }; + + checkCreateAdminLink=function(callbackFn){ + $.ajax("restServices/redbackServices/userService/isAdminUserExists", { + type: "GET", + dataType: 'json', + success: function(data) { + var adminExists = data; + window.archivaModel.adminExists=adminExists; + var createAdminLink=$("#create-admin-link"); + if (adminExists == false) { + createAdminLink.show(); + $("#login-link").hide(); + $("#register-link").hide(); + } else { + createAdminLink.hide(); + } + if(callbackFn){ + callbackFn() + } + $.log("adminExists:"+adminExists); + } + }); + }; + + // handle url with registration link + checkUrlParams=function(){ + var validateMeId = $.urlParam('validateMe'); + if (validateMeId) { + validateKey(validateMeId); + return; + } + var resetPassword= $.urlParam('resetPassword'); + if (resetPassword){ + resetPasswordForm(resetPassword); + return; + } + + var matches = window.location.toString().match(/^[^#]*(#.+)$/); + var hash = matches ? matches[1] : ''; + $.log("location:"+window.sammyArchivaApplication.getLocation()+",hash:"+hash); + // by default display welcome screen + if(!hash){ + window.sammyArchivaApplication.setLocation("#welcome"); + } + + }; + + hasKarma=function(karmaName){ + return $.inArray(karmaName,window.redbackModel.operatioNames)>=0; + }; + + startArchivaApplication=function(){ + + $.log("startArchivaApplication"); + loadRedbackTemplate(); + loadArchivaTemplate(); + $('#topbar-menu-container').html($("#topbar_menu_tmpl" ).tmpl()); + $('#sidebar-content').html($("#main_menu_tmpl").tmpl()); + + ko.bindingHandlers.redbackP = { + init: function(element, valueAccessor) { + $(element).attr("redback-permissions",valueAccessor); + } + }; + + ko.applyBindings(new MainMenuViewModel()); + + hideElementWithKarma(); + checkSecurityLinks(); + checkCreateAdminLink(); + $('#footer-content').html($('#footer-tmpl').tmpl(window.archivaRuntimeInfo)); + + updateAppearanceToolBar(); + + window.sammyArchivaApplication.run(); + + }; + + drawQuickSearchAutocomplete=function(){ + + $( "#quick-search-autocomplete" ).autocomplete({ + minLength: 3, + delay: 600, + source: function(request, response){ + $.get("restServices/archivaServices/searchService/quickSearch?queryString="+encodeURIComponent(request.term), + function(data) { + var res = mapArtifacts(data); + var uniqId = []; + var uniqArtifactIds=[]; + for (var i= 0;i<res.length;i++){ + if ( $.inArray(res[i].artifactId,uniqId)<0){ + uniqId.push(res[i].artifactId); + uniqArtifactIds.push(res[i]); + } + } + response(uniqArtifactIds); + } + ); + }, + select: function( event, ui ) { + $.log("select artifactId:"+ui.item.artifactId); + window.sammyArchivaApplication.setLocation("#quicksearch~"+ui.item.artifactId); + } + }).data( "autocomplete" )._renderItem = function( ul, item ) { + return $( "<li></li>" ) + .data( "item.autocomplete", item ) + .append( "<a>" + item.artifactId + "</a>" ) + .appendTo( ul ); + }; + + } + + +}); + diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/network-proxies.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/network-proxies.js new file mode 100644 index 000000000..13a5a8cd8 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/network-proxies.js @@ -0,0 +1,323 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +define("archiva.network-proxies",["jquery","i18n","jquery.tmpl","bootstrap","jquery.validate","knockout" + ,"knockout.simpleGrid"], function(jquery,i18n,jqueryTmpl,bootstrap,jqueryValidate,ko) { + + + NetworkProxy=function(id,protocol,host,port,username,password,useNtlm){ + var self=this; + //private String id; + this.id = ko.observable(id); + this.id.subscribe(function(newValue){self.modified(true)}); + + //private String protocol = "http"; + this.protocol=ko.observable(protocol); + this.protocol.subscribe(function(newValue){self.modified(true)}); + + //private String host; + this.host=ko.observable(host); + this.host.subscribe(function(newValue){self.modified(true)}); + + //private int port = 8080; + this.port=ko.observable(port); + this.port.subscribe(function(newValue){self.modified(true)}); + + //private String username; + this.username=ko.observable(username?username:""); + this.username.subscribe(function(newValue){self.modified(true)}); + + //private String password; + this.password=ko.observable(password?password:""); + this.password.subscribe(function(newValue){self.modified(true)}); + + //use NTLM proxy + this.useNtlm=ko.observable(useNtlm?useNtlm:false); + this.useNtlm.subscribe(function(newValue){self.modified(true)}); + + this.modified=ko.observable(false); + } + + NetworkProxyViewModel=function(networkProxy, update, networkProxiesViewModel,bulkMode){ + this.update=update; + this.networkProxy=networkProxy; + this.networkProxiesViewModel=networkProxiesViewModel; + var self=this; + this.bulkMode=false || bulkMode; + + this.save=function(){ + if (!$("#main-content" ).find("#network-proxy-edit-form").valid()){ + return; + } + if (!this.bulkMode){ + clearUserMessages(); + } + if (update){ + $.ajax("restServices/archivaServices/networkProxyService/updateNetworkProxy", + { + type: "POST", + contentType: 'application/json', + data: ko.toJSON(networkProxy), + dataType: 'json', + success: function(data) { + $.log("update proxy id:"+self.networkProxy.id()); + var message=$.i18n.prop('networkproxy.updated',self.networkProxy.id()); + displaySuccessMessage(message); + self.networkProxy.modified(false); + if (!this.bulkMode){ + activateNetworkProxiesGridTab(); + } + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + } + } + ); + } else { + + $.ajax("restServices/archivaServices/networkProxyService/addNetworkProxy", + { + type: "POST", + contentType: 'application/json', + data: ko.toJSON(networkProxy), + dataType: 'json', + success: function(data) { + self.networkProxy.modified(false); + self.networkProxiesViewModel.networkProxies.push(self.networkProxy); + displaySuccessMessage($.i18n.prop('networkproxy.added',self.networkProxy.id())); + activateNetworkProxiesGridTab(); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + } + } + ); + + } + } + + displayGrid=function(){ + activateNetworkProxiesGridTab(); + } + } + + NetworkProxiesViewModel=function(){ + this.networkProxies=ko.observableArray([]); + + var self=this; + + this.gridViewModel = null; + + editNetworkProxy=function(networkProxy){ + clearUserMessages(); + $.log("editNetworkProxy"); + var mainContent = $("#main-content"); + mainContent.find("#network-proxies-view-tabs-li-edit a").html($.i18n.prop("edit")); + var viewModel = new NetworkProxyViewModel(networkProxy,true,self); + ko.applyBindings(viewModel,mainContent.find("#network-proxies-edit").get(0)); + activateNetworkProxyFormValidation(); + activateNetworkProxyEditTab(); + mainContent.find("#network-proxy-btn-save").attr("disabled","true"); + mainContent.find("#network-proxy-btn-save").button('toggle'); + } + + this.bulkSave=function(){ + return getModifiedNetworkProxies().length>0; + } + + getModifiedNetworkProxies=function(){ + var prx = $.grep(self.networkProxies(), + function (networkProxy,i) { + return networkProxy.modified(); + }); + return prx; + } + + + updateModifiedNetworkProxies=function(){ + var modifiedNetworkProxies = getModifiedNetworkProxies(); + + openDialogConfirm(function(){ + for(var i=0;i<modifiedNetworkProxies.length;i++){ + var viewModel = new NetworkProxyViewModel(modifiedNetworkProxies[i],true,self,false); + viewModel.save(); + } + closeDialogConfirm(); + }, + $.i18n.prop('ok'), + $.i18n.prop('cancel'), + $.i18n.prop('networkproxy.bulk.save.confirm.title'), + $.i18n.prop('networkproxy.bulk.save.confirm',modifiedNetworkProxies.length)); + + + } + + updateNetworkProxy=function(networkProxy){ + var viewModel = new NetworkProxyViewModel(networkProxy,true,self,false); + viewModel.save(); + } + + removeNetworkProxy=function(networkProxy){ + openDialogConfirm( + function(){ + $.ajax("restServices/archivaServices/networkProxyService/deleteNetworkProxy/"+encodeURIComponent(networkProxy.id()), + { + type: "get", + success: function(data) { + self.networkProxies.remove(networkProxy); + clearUserMessages(); + displaySuccessMessage($.i18n.prop('networkproxy.deleted',networkProxy.id())); + activateNetworkProxiesGridTab(); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + }, + complete: function(){ + closeDialogConfirm(); + } + } + )}, $.i18n.prop('ok'), $.i18n.prop('cancel'), $.i18n.prop('networkproxy.delete.confirm',networkProxy.id()), + $("#network-proxy-delete-warning-tmpl" ).tmpl(networkProxy)); + } + } + + + displayNetworkProxies=function(){ + screenChange(); + var mainContent = $("#main-content"); + mainContent.html(mediumSpinnerImg()); + + + + loadNetworkProxies( function(data) { + var networkProxiesViewModel = new NetworkProxiesViewModel(); + mainContent.html($("#networkProxiesMain").tmpl()); + mainContent.find("#network-proxies-view-tabs a:first").tab('show'); + + mainContent.find("#network-proxies-view-tabs").on('show', function (e) { + if ($(e.target).attr("href")=="#network-proxies-edit") { + var viewModel = new NetworkProxyViewModel(new NetworkProxy(),false,networkProxiesViewModel); + ko.applyBindings(viewModel,$("#main-content" ).find("#network-proxies-edit").get(0)); + activateNetworkProxyFormValidation(); + clearUserMessages(); + } + if ($(e.target).attr("href")=="#network-proxies-view") { + $("#main-content" ).find("#network-proxies-view-tabs-li-edit a").html($.i18n.prop("add")); + clearUserMessages(); + } + + }); + networkProxiesViewModel.networkProxies(mapNetworkProxies(data)); + networkProxiesViewModel.gridViewModel = new ko.simpleGrid.viewModel({ + data: networkProxiesViewModel.networkProxies, + columns: [ + { + headerText: $.i18n.prop('identifier'), + rowText: "id" + }, + { + headerText: $.i18n.prop('protocol'), + rowText: "protocol" + }, + { + headerText: $.i18n.prop('host'), + rowText: "host" + }, + { + headerText: $.i18n.prop('port'), + rowText: "port" + }, + { + headerText: $.i18n.prop('username'), + rowText: "username" + } + ], + pageSize: 5, + gridUpdateCallBack: function(networkProxy){ + $("#main-content" ).find("#networkProxiesTable [title]").tooltip(); + } + }); + ko.applyBindings(networkProxiesViewModel,$("#main-content" ).find("#network-proxies-view").get(0)); + } + ) + } + + loadNetworkProxies=function(successCallbackFn, errorCallbackFn){ + $.ajax("restServices/archivaServices/networkProxyService/getNetworkProxies", { + type: "GET", + dataType: 'json', + success: successCallbackFn, + error: errorCallbackFn + }); + } + + activateNetworkProxyFormValidation=function(){ + var editForm=$("#main-content" ).find("#network-proxy-edit-form"); + var validator = editForm.validate({ + rules: {id: { + required: true, + remote: { + url: "restServices/archivaUiServices/dataValidatorService/networkProxyIdNotExists", + type: "get" + } + }}, + showErrors: function(validator, errorMap, errorList) { + customShowError(editForm,validator,errorMap,errorMap); + } + }); + validator.settings.messages["id"]=$.i18n.prop("id.required.or.alreadyexists"); + } + + activateNetworkProxiesGridTab=function(){ + var mainContent = $("#main-content"); + mainContent.find("#network-proxies-view-tabs-li-edit").removeClass("active"); + mainContent.find("#network-proxies-edit").removeClass("active"); + + mainContent.find("#network-proxies-view-tabs-li-grid").addClass("active"); + mainContent.find("#network-proxies-view").addClass("active"); + mainContent.find("#network-proxies-view-tabs-li-edit a").html($.i18n.prop("add")); + + } + + activateNetworkProxyEditTab=function(){ + var mainContent = $("#main-content"); + mainContent.find("#network-proxies-view-tabs-li-grid").removeClass("active"); + mainContent.find("#network-proxies-view").removeClass("active"); + + mainContent.find("#network-proxies-view-tabs-li-edit").addClass("active"); + mainContent.find("#network-proxies-edit").addClass("active"); + } + + mapNetworkProxy=function(data){ + if (data==null){ + return null; + } + return new NetworkProxy(data.id,data.protocol,data.host,data.port,data.username,data.password,data.useNtlm); + } + + mapNetworkProxies=function(data){ + var mappedNetworkProxies = $.map(data, function(item) { + return mapNetworkProxy(item); + }); + return mappedNetworkProxies; + } + +});
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/proxy-connectors-rules.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/proxy-connectors-rules.js new file mode 100644 index 000000000..e8b9ca74f --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/proxy-connectors-rules.js @@ -0,0 +1,376 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +define("archiva.proxy-connectors-rules",["jquery","i18n","jquery.tmpl","bootstrap","jquery.ui","knockout" + ,"knockout.simpleGrid","knockout.sortable","archiva.proxy-connectors"], + function(jquery,i18n,jqueryTmpl,bootstrap,jqueryUi,ko) { + + ProxyConnectorRulesViewModel=function(proxyConnectorRules,proxyConnectors){ + var self=this; + self.proxyConnectorRules=ko.observableArray(proxyConnectorRules?proxyConnectorRules:[]); + self.proxyConnectors=ko.observableArray(proxyConnectors); + self.proxyConnectors.id="select"; + + // FIXME get that from a REST service + // FIXME i18n + this.ruleTypes=[new RuleType("BLACK_LIST","Black list","images/red-22-22.png"),new RuleType("WHITE_LIST","White list","images/green-22-22.png")]; + + this.findRuleType=function(proxyConnectorRule){ + var ruleType; + $.each(self.ruleTypes, function(index, value) { + if(value.type==proxyConnectorRule.proxyConnectorRuleType()){ + ruleType=value; + } + }); + return ruleType; + } + + this.findProxyConnector=function(sourceRepoId,targetRepoId){ + for(var i=0;i<self.proxyConnectors().length;i++){ + var proxyConnector=self.proxyConnectors()[i]; + if(proxyConnector.sourceRepoId()==sourceRepoId && proxyConnector.targetRepoId()==targetRepoId){ + return proxyConnector; + } + } + } + + this.displayGrid=function(){ + var mainContent = $("#main-content"); + + $.each(self.proxyConnectorRules(), function(index, value) { + value.ruleType=self.findRuleType(value); + }); + + this.gridViewModel = new ko.simpleGrid.viewModel({ + data: self.proxyConnectorRules, + pageSize: 5, + gridUpdateCallBack: function(){ + //$("#main-content" ).find("#proxy-connectors-rules-view-tabsTable" ).find("[title]").tooltip(); + } + }); + + ko.applyBindings(self,mainContent.find("#proxy-connector-rules-view").get(0)); + + removeSmallSpinnerImg(mainContent); + + mainContent.find("#proxy-connectors-rules-view-tabs").on('show', function (e) { + $.log("on show:"+$(e.target).attr("href")); + if ($(e.target).attr("href")=="#proxy-connector-rules-edit") { + var proxyConnectorRuleViewModel = new ProxyConnectorRuleViewModel(new ProxyConnectorRule(),self,false); + ko.applyBindings(proxyConnectorRuleViewModel,mainContent.find("#proxy-connector-rules-edit" ).get(0)); + activateProxyConnectorRulesEditTab(); + } + }); + } + addProxyConnectorRule=function(proxyConnectorRule){ + $("#proxy-connector-rule-add-btn" ).button("loading"); + $.log("addProxyConnectorRule"); + self.saveProxyConnectorRule(proxyConnectorRule,"restServices/archivaServices/proxyConnectorRuleService/proxyConnectorRule",true, + function(){ + $("#proxy-connector-rule-add-btn" ).button("reset"); + }); + } + + this.saveProxyConnectorRule=function(proxyConnectorRule,url,add,completeFnCallback){ + $.log("saveProxyConnectorRule:"+url); + var userMessages=$("#user-messages"); + userMessages.html(mediumSpinnerImg()); + $.ajax(url, + { + type: "POST", + contentType: 'application/json', + data: ko.toJSON(proxyConnectorRule), + dataType: 'json', + success: function(data) { + $.log("save proxyConnectorRule pattern:"+proxyConnectorRule.pattern()); + var message=$.i18n.prop(add?'proxy-connector-rule.added':'proxy-connector-rule.updated',proxyConnectorRule.pattern()); + displaySuccessMessage(message); + proxyConnectorRule.modified(false); + if(add){ + // add rule type for image + proxyConnectorRule.ruleType=self.findRuleType(proxyConnectorRule); + self.proxyConnectorRules.push(proxyConnectorRule); + } + activateProxyConnectorRulesGridTab(); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + }, + complete:function(data){ + removeMediumSpinnerImg(userMessages); + if(completeFnCallback){ + completeFnCallback(); + } + } + } + ); + } + + updateProxyConnectorRule=function(proxyConnectorRule){ + $.log("updateProxyConnectorRule"); + $("#main-content" ).find("#proxy-connectors-rules-edit-div").find("#proxy-connector-rule-update-btn").button("loading"); + self.saveProxyConnectorRule(proxyConnectorRule,"restServices/archivaServices/proxyConnectorRuleService/updateProxyConnectorRule", + false, + function(){ + $("#proxy-connector-rule-update-btn" ).button("reset"); + } + ); + } + + this.deleteProxyConnectorRule=function(proxyConnectorRule){ + $("#main-content" ).find("proxy-connectors-rules-view-tabsTable").find(".btn").button("loading"); + var userMessages=$("#user-messages"); + userMessages.html(mediumSpinnerImg()); + $.ajax("restServices/archivaServices/proxyConnectorRuleService/deleteProxyConnectorRule", + { + type:"POST", + contentType: 'application/json', + data: ko.toJSON(proxyConnectorRule), + dataType: 'json', + success:function(data){ + var message=$.i18n.prop('proxy-connector-rule.deleted',proxyConnectorRule.pattern()); + self.proxyConnectorRules.remove(proxyConnectorRule); + displaySuccessMessage(message); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + }, + complete:function(data){ + removeMediumSpinnerImg(userMessages); + $("#main-content" ).find("proxy-connectors-rules-view-tabsTable").find(".btn").button("reset"); + } + } + ); + } + + removeProxyConnectorRule=function(proxyConnectorRule){ + + openDialogConfirm( + function(){self.deleteProxyConnectorRule(proxyConnectorRule);window.modalConfirmDialog.modal('hide')}, + $.i18n.prop('ok'), $.i18n.prop('cancel'), + $.i18n.prop('proxy-connector-rule.delete.confirm',proxyConnectorRule.pattern()),""); + + } + + editProxyConnectorRule=function(proxyConnectorRule){ + var proxyConnectorRuleViewModel=new ProxyConnectorRuleViewModel(proxyConnectorRule,self,true); + ko.applyBindings(proxyConnectorRuleViewModel,$("#main-content").find("#proxy-connector-rules-edit" ).get(0)); + activateProxyConnectorRulesEditTab(); + proxyConnectorRuleViewModel.activateRemoveChoosen(self); + proxyConnectorRuleViewModel.activateRemoveAvailable(self); + } + + remove=function(){ + $.log("remove"); + } + + } + + ProxyConnectorRuleViewModel=function(proxyConnectorRule,proxyConnectorRulesViewModel,update){ + var self=this; + this.proxyConnectorRule=proxyConnectorRule; + this.proxyConnectorRulesViewModel=proxyConnectorRulesViewModel; + this.availableProxyConnectors=ko.observableArray([]); + this.availableProxyConnectors.id="availableProxyConnectors"; + this.update=update; + + $.each(this.proxyConnectorRulesViewModel.proxyConnectors(), function(idx, value) { + //$.log(idx + ': ' + value.sourceRepoId() +":"+value.targetRepoId()); + var available=true; + // is it in proxyConnectorRule.proxyConnectors + $.each(self.proxyConnectorRule.proxyConnectors(),function(index,proxyConnector){ + if(value.sourceRepoId()==proxyConnector.sourceRepoId() && value.targetRepoId()==proxyConnector.targetRepoId()){ + available=false; + } + }); + if(available==true){ + self.availableProxyConnectors.push(value); + } + }); + + proxyConnectorMoved=function(arg){ + $.log("repositoryMoved:"+arg.sourceIndex+" to " + arg.targetIndex); + self.proxyConnectorRule.modified(true); + self.activateRemoveChoosen(self.proxyConnectorRulesViewModel); + self.activateRemoveAvailable(self.proxyConnectorRulesViewModel); + } + + saveProxyConnectorRule=function(){ + self.proxyConnectorRulesViewModel.saveProxyConnectorRule(self.proxyConnectorRule) + } + + this.removeChoosen=function(proxyConnectorRulesViewModel,sourceRepoId,targetRepoId){ + $.log("removeChoosen:"+sourceRepoId+":"+targetRepoId); + + $.log("size before:"+self.proxyConnectorRule.proxyConnectors().length); + var proxyConnectorToRemove=null; + for(var i=0;i<self.proxyConnectorRule.proxyConnectors().length;i++){ + if(self.proxyConnectorRule.proxyConnectors()[i].sourceRepoId()==sourceRepoId && + self.proxyConnectorRule.proxyConnectors()[i].targetRepoId()==targetRepoId){ + proxyConnectorToRemove=self.proxyConnectorRule.proxyConnectors()[i]; + } + } + self.proxyConnectorRule.proxyConnectors.remove(proxyConnectorToRemove); + self.availableProxyConnectors.push(proxyConnectorToRemove); + $.log("size after:"+self.proxyConnectorRule.proxyConnectors().length); + var mainContent=$("#main-content"); + mainContent.find("#proxy-connectors-rules-available-proxy-connectors" ).find("[data-source-repoId="+sourceRepoId+"][data-target-repoId="+targetRepoId+"]" ).on("click", function(){ + self.removeAvailable(proxyConnectorRulesViewModel,$(this).attr("data-source-repoId"),$(this).attr("data-target-repoId")); + }); + mainContent.find("#proxy-connectors-rules-edit-order-div" ).find("[data-source-repoId="+sourceRepoId+"][data-target-repoId="+targetRepoId+"]" ).off("click"); + } + + this.activateRemoveChoosen=function(proxyConnectorRulesViewModel){ + $("#main-content" ).find("#proxy-connectors-rules-edit-order-div" ).find(".icon-minus-sign" ).on("click", function(){ + self.removeChoosen(proxyConnectorRulesViewModel,$(this).attr("data-source-repoId"),$(this).attr("data-target-repoId")); + }); + } + + this.removeAvailable=function(proxyConnectorRulesViewModel,sourceRepoId,targetRepoId){ + $.log("removeAvailable:"+sourceRepoId+":"+targetRepoId); + + $.log("size before:"+self.availableProxyConnectors().length); + var proxyConnectorToAdd=null; + for(var i=0;i<self.availableProxyConnectors().length;i++){ + if(self.availableProxyConnectors()[i].sourceRepoId()==sourceRepoId && + self.availableProxyConnectors()[i].targetRepoId()==targetRepoId){ + $.log("found"); + proxyConnectorToAdd=self.availableProxyConnectors()[i]; + } + } + self.proxyConnectorRule.proxyConnectors.push(proxyConnectorToAdd); + self.availableProxyConnectors.remove(proxyConnectorToAdd); + $.log("size after:"+self.availableProxyConnectors().length); + var mainContent=$("#main-content"); + mainContent.find("#proxy-connectors-rules-edit-order-div" ).find("[data-source-repoId="+sourceRepoId+"][data-target-repoId="+targetRepoId+"]" ).on("click", function(){ + self.removeChoosen(proxyConnectorRulesViewModel,$(this).attr("data-source-repoId"),$(this).attr("data-target-repoId")); + }); + mainContent.find("#proxy-connectors-rules-available-proxy-connectors" ).find("[data-source-repoId="+sourceRepoId+"][data-target-repoId="+targetRepoId+"]" ).off("click"); + } + + this.activateRemoveAvailable=function(proxyConnectorRulesViewModel){ + $("#main-content" ).find("#proxy-connectors-rules-available-proxy-connectors" ).find(".icon-plus-sign" ).on("click", function(){ + self.removeAvailable(proxyConnectorRulesViewModel,$(this).attr("data-source-repoId"),$(this).attr("data-target-repoId")); + }); + } + + } + + + displayProxyConnectorsRules=function(){ + $.log("displayProxyConnectorsRules"); + screenChange(); + var mainContent = $("#main-content"); + mainContent.html($("#proxyConnectorsRulesMain").tmpl()); + var userMessages=$("#user-messages"); + userMessages.html(mediumSpinnerImg()); + loadAllProxyConnectors(function(data){ + var proxyConnectors = mapProxyConnectors(data); + + $.ajax("restServices/archivaServices/proxyConnectorRuleService/proxyConnectorRules", { + type: "GET", + dataType: 'json', + success: function (data){ + var proxyConnectorRules=mapProxyConnectorRules(data); + var proxyConnectorRulesViewModel = new ProxyConnectorRulesViewModel(proxyConnectorRules,proxyConnectors); + proxyConnectorRulesViewModel.displayGrid(); + activateProxyConnectorRulesGridTab(); + }, + complete: function(data){ + removeMediumSpinnerImg(userMessages); + } + + }); + + }); + } + + ProxyConnectorRule=function(pattern,proxyConnectorRuleType,proxyConnectors){ + //private String pattern; + var self=this; + + this.modified=ko.observable(false); + + //private String sourceRepoId; + this.pattern=ko.observable(pattern); + this.pattern.subscribe(function(newValue){ + self.modified(true); + }); + + this.ruleType=null; + + //private ProxyConnectorRuleType proxyConnectorRuleType; + this.proxyConnectorRuleType=ko.observable(proxyConnectorRuleType); + this.proxyConnectorRuleType.subscribe(function(newValue){ + self.modified(true); + }); + + //private List<ProxyConnector> proxyConnectors; + this.proxyConnectors=ko.observableArray(proxyConnectors?proxyConnectors:[]); + this.proxyConnectors.subscribe(function(newValue){ + self.modified(true); + }); + + this.ruleType=null; + } + + mapProxyConnectorRule=function(data){ + if (data==null){ + return null; + } + return new ProxyConnectorRule(data.pattern, data.proxyConnectorRuleType, mapProxyConnectors(data.proxyConnectors)); + } + + mapProxyConnectorRules=function(data){ + var mappedProxyConnectorRules = $.map(data, function(item) { + return mapProxyConnectorRule(item); + }); + return mappedProxyConnectorRules; + } + + + activateProxyConnectorRulesGridTab=function(){ + var mainContent = $("#main-content"); + mainContent.find("#proxy-connectors-rules-view-tabs-content div[class*='tab-pane']").removeClass("active"); + mainContent.find("#proxy-connectors-rules-view-tabs li").removeClass("active"); + + mainContent.find("#proxy-connector-rules-view").addClass("active"); + mainContent.find("#proxy-connectors-rules-view-tabs-li-grid").addClass("active"); + mainContent.find("#proxy-connectors-rules-view-tabs-a-edit").html($.i18n.prop("add")); + + } + + activateProxyConnectorRulesEditTab=function(){ + var mainContent = $("#main-content"); + + mainContent.find("#proxy-connectors-rules-view-tabs-content div[class*='tab-pane']").removeClass("active"); + mainContent.find("#proxy-connectors-rules-view-tabs > li").removeClass("active"); + + mainContent.find("#proxy-connector-rules-edit").addClass("active"); + mainContent.find("#proxy-connectors-rules-view-tabs-edit").addClass("active"); + } + + RuleType=function(type,label,image){ + this.type=type; + this.label=label; + this.image=image; + } + +}); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/proxy-connectors.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/proxy-connectors.js new file mode 100644 index 000000000..ec6787606 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/proxy-connectors.js @@ -0,0 +1,673 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +define("archiva.proxy-connectors",["jquery","i18n","jquery.tmpl","bootstrap","jquery.validate","knockout" + ,"knockout.simpleGrid","knockout.sortable","select2"], + function(jquery,i18n,jqueryTmpl,bootstrap,jqueryValidate,ko) { + + ProxyConnector=function(sourceRepoId,targetRepoId,proxyId,blackListPatterns,whiteListPatterns,policiesEntries,propertiesEntries, + disabled,order){ + var self=this; + + this.modified=ko.observable(false); + + //private String sourceRepoId; + this.sourceRepoId=ko.observable(sourceRepoId); + this.sourceRepoId.subscribe(function(newValue){ + self.modified(true); + }); + + //private String targetRepoId; + this.targetRepoId=ko.observable(targetRepoId); + this.targetRepoId.subscribe(function(newValue){ + self.modified(true); + }); + + this.previousProxyId=proxyId; + + //private String proxyId; + this.proxyId=ko.observable(proxyId); + this.proxyId.subscribe(function(newValue){ + if(newValue!=self.previousProxyId){ + $.log("proxyId modified:"+newValue+",previous:"+self.previousProxyId); + self.previousProxyId=newValue; + self.modified(true); + } + }); + + //private List<String> blackListPatterns; + this.blackListPatterns=ko.observableArray(blackListPatterns==null?[]:blackListPatterns); + this.blackListPatterns.subscribe(function(newValue){ + self.modified(true); + }); + + //private List<String> whiteListPatterns; + this.whiteListPatterns=ko.observableArray(whiteListPatterns==null?[]:whiteListPatterns); + this.whiteListPatterns.subscribe(function(newValue){ + self.modified(true); + }); + + //private List<PropertyEntry> policiesEntries; + this.policiesEntries=ko.observableArray(policiesEntries==null?new Array():policiesEntries); + this.policiesEntries.subscribe(function(newValue){ + self.modified(true); + }); + + //private List<PropertyEntry> properties; + this.propertiesEntries=ko.observableArray(propertiesEntries==null?new Array():propertiesEntries); + this.propertiesEntries.subscribe(function(newValue){ + self.modified(true); + }); + + //private boolean disabled = false; + this.disabled=ko.observable(disabled); + this.disabled.subscribe(function(newValue){ + self.modified(true); + }); + + //private int order = 0; + this.order=ko.observable(order?order:0); + this.order.subscribe(function(newValue){ + self.modified(true); + }); + + + + this.updatePolicyEntry=function(key,value){ + $.log("updatePolicyEntry:"+key+":"+value); + var found=false; + for(var i=0;i<self.policiesEntries().length;i++){ + if (self.policiesEntries()[i].key==key){ + self.policiesEntries()[i].value=value; + found=true; + self.modified(true); + } + } + if(!found){ + self.policiesEntries().push(new Entry(key,value)); + } + } + + } + + PolicyInformation=function(options,defaultOption,id,name){ + + var self=this; + this.modified=ko.observable(false); + + //private List<String> options; + this.options=ko.observableArray(options); + this.options.subscribe(function(newValue){self.modified(true)}); + + //private String defaultOption; + this.defaultOption=ko.observable(defaultOption); + this.defaultOption.subscribe(function(newValue){self.modified(true)}); + + //private String id; + this.id=ko.observable(id); + this.id.subscribe(function(newValue){self.modified(true)}); + + //private String name; + this.name=ko.observable(name); + this.name.subscribe(function(newValue){self.modified(true)}); + + } + + ProxyConnectorViewModel=function(proxyConnector,update,proxyConnectorsViewModel){ + var self=this; + this.proxyConnector=proxyConnector; + this.proxyConnectorsViewModel=proxyConnectorsViewModel; + this.update=update; + this.modified=ko.observable(false); + + isUpdate=function(){ + return self.update; + } + + getSelectedPolicyOption=function(id){ + var policiesEntries=self.proxyConnector.policiesEntries(); + if (policiesEntries!=null){ + for (i=0;i<policiesEntries.length;i++){ + var curKey = $.isFunction(policiesEntries[i].key)? policiesEntries[i].key():policiesEntries[i].key; + if (id==curKey){ + return $.isFunction(policiesEntries[i].value)? policiesEntries[i].value():policiesEntries[i].value; + } + } + } + return ""; + } + + changePolicyOption=function(id){ + var selectedOption=$("#main-content").find("#policy-"+id ).find("option:selected"); + if (selectedOption.length>0){ + var value = selectedOption.val(); + $.log("changePolicyOption:"+id+":"+value); + self.proxyConnector.updatePolicyEntry(id,value); + + } + } + + + getPolicyOptions=function(id){ + var policyInformations=self.proxyConnectorsViewModel.policyInformations(); + for(var i=0;i<policyInformations.length;i++){ + if (policyInformations[i].id()==id){ + return policyInformations[i].options(); + } + } + } + + + + addBlacklistPattern=function(){ + var pattern = $("#main-content").find("#blacklist-value").val(); + var tab = self.proxyConnector.blackListPatterns(); + tab.push(pattern); + self.proxyConnector.blackListPatterns(tab); + self.proxyConnector.modified(true); + } + + removeBlacklistPattern=function(pattern){ + self.proxyConnector.blackListPatterns.remove(pattern); + self.proxyConnector.modified(true); + } + + addWhitelistPattern=function(){ + var pattern = $("#main-content" ).find("#whitelist-value").val(); + var tab = self.proxyConnector.whiteListPatterns(); + tab.push(pattern); + self.proxyConnector.whiteListPatterns(tab); + self.proxyConnector.modified(true); + + } + + removeWhitelistPattern=function(pattern){ + self.proxyConnector.whiteListPatterns.remove(pattern); + self.proxyConnector.modified(true); + } + + this.save=function(){ + //FIXME data controls !!! + clearUserMessages(); + var userMessages=$("#user-messages"); + userMessages.html(mediumSpinnerImg()); + $("#proxy-connector-btn-save" ).button("loading"); + // update is delete then add + if (this.update){ + $.ajax("restServices/archivaServices/proxyConnectorService/updateProxyConnector", + { + type: "POST", + data: ko.toJSON(self.proxyConnector), + contentType: 'application/json', + dataType: 'json', + success: function(data) { + displaySuccessMessage($.i18n.prop('proxyconnector.updated')); + activateProxyConnectorsGridTab(); + self.proxyConnector.modified(false); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + }, + complete: function(){ + removeMediumSpinnerImg(userMessages); + $("#proxy-connector-btn-save" ).button("reset"); + } + } + ); + } else { + + $.ajax("restServices/archivaServices/proxyConnectorService/addProxyConnector", + { + type: "POST", + data: ko.toJSON(self.proxyConnector), + contentType: 'application/json', + dataType: 'json', + success: function(data) { + displaySuccessMessage($.i18n.prop('proxyconnector.added')); + activateProxyConnectorsGridTab(); + self.proxyConnector.modified(false); + self.proxyConnectorsViewModel.proxyConnectors.push(self.proxyConnector); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + }, + complete: function(){ + removeMediumSpinnerImg(userMessages); + $("#proxy-connector-btn-save" ).button("reset"); + } + } + ); + } + } + + this.deleteProperty=function(key){ + for(var i=0;i<self.proxyConnector.propertiesEntries().length;i++){ + var entry=self.proxyConnector.propertiesEntries()[i]; + if (entry.key()==key()){ + self.proxyConnector.propertiesEntries.remove(entry); + self.proxyConnector.modified(true); + } + } + + } + + this.addProperty=function(){ + var mainContent=$("#main-content"); + var key=mainContent.find("#property-key").val(); + var value=mainContent.find("#property-value").val(); + var oldTab = self.proxyConnector.propertiesEntries(); + oldTab.push(new Entry(key,value)); + self.proxyConnector.propertiesEntries(oldTab); + mainContent.find("#property-key").val(""); + mainContent.find("#property-value").val(""); + self.proxyConnector.modified(true); + } + + displayGrid=function(){ + activateProxyConnectorsGridTab(); + } + } + + ProxyConnectorsViewModel=function(){ + var self=this; + this.proxyConnectors=ko.observableArray([]); + this.proxyConnectors.subscribe(function(newValue){ + $.log("ProxyConnectorsViewModel#proxyConnectors modified"); + self.proxyConnectors().sort(function(a,b){ + if ( a.sourceRepoId()== b.sourceRepoId()) return a.order() - b.order(); + return (a.sourceRepoId() > b.sourceRepoId())? -1:1; + }); + }); + this.policyInformations=ko.observableArray([]); + this.managedRepositories=ko.observableArray([]); + this.remoteRepositories=ko.observableArray([]); + this.networkProxies=ko.observableArray([]); + + this.bulkSave=function(){ + return getModifiedProxyConnectors().length>0; + } + + getModifiedProxyConnectors=function(){ + var prx = $.grep(self.proxyConnectors(), + function (proxyConnector,i) { + return proxyConnector.modified(); + }); + return prx; + } + + this.updateModifiedProxyConnectors=function(){ + var modifiedProxyConnectors = getModifiedProxyConnectors(); + + openDialogConfirm(function(){ + for(var i=0;i<modifiedProxyConnectors.length;i++){ + var viewModel = new ProxyConnectorViewModel(modifiedProxyConnectors[i],true,self,false); + viewModel.save(); + } + closeDialogConfirm(); + }, + $.i18n.prop('ok'), + $.i18n.prop('cancel'), + $.i18n.prop('proxy-connectors.bulk.save.confirm.title'), + $.i18n.prop('proxy.connector.bulk.save.confirm',modifiedProxyConnectors.length)); + } + + updateProxyConnector=function(proxyConnector){ + var viewModel = new ProxyConnectorViewModel(proxyConnector,true,self,false); + viewModel.save(); + } + + editProxyConnector=function(proxyConnector){ + var proxyConnectorViewModel=new ProxyConnectorViewModel(proxyConnector,true,self); + var mainContent = $("#main-content"); + mainContent.find("#proxy-connectors-edit").html($("#proxy-connector-edit-form-tmpl").tmpl()); + ko.applyBindings(proxyConnectorViewModel,mainContent.find("#proxy-connectors-edit").get(0)); + activateProxyConnectorsEditTab(); + mainContent.find("#proxy-connectors-view-tabs-li-edit a").html($.i18n.prop("edit")); + } + + deleteProxyConnector=function(proxyConnector){ + + openDialogConfirm( + function(){ + clearUserMessages(); + removeProxyConnector(proxyConnector,function(){ + displaySuccessMessage($.i18n.prop('proxyconnector.removed')); + self.proxyConnectors.remove(proxyConnector); + closeDialogConfirm(); + })}, $.i18n.prop('ok'), $.i18n.prop('cancel'), $.i18n.prop('proxyconnector.delete.confirm'), + $("#proxy-connector-delete-warning-tmpl").tmpl(proxyConnector)); + + + } + + + getManagedRepository=function(id){ + return findManagedRepository(id,self.managedRepositories()); + } + + getRemoteRepository=function(id){ + var remoteRepository=$.grep(self.remoteRepositories(), + function(repo,idx){ + return repo.id()==id; + } + ); + return ($.isArray(remoteRepository) && remoteRepository.length>0) ? remoteRepository[0]:new RemoteRepository(); + } + + getProxyConnector=function(sourceRepoId,targetRepoId){ + var proxyConnectors=$.grep(self.proxyConnectors(), + function(proxyConnector,idx){ + return proxyConnector.sourceRepoId()==sourceRepoId + && proxyConnector.targetRepoId()==targetRepoId; + } + ); + var res = ($.isArray(proxyConnectors) && proxyConnectors.length>0) ? proxyConnectors[0]:new ProxyConnector(); + return res; + } + showSettings=function(){ + $.log("showSettings"); + $("#body_content" ).find(".popover" ).hide(); + //$("#main-content").find("[id^='proxy-connectors-grid-remoterepo-settings-edit-']" ).popover("hide"); + } + buildSettings=function(proxyConnector){ + var tmplHtml = $("#proxy-connectors-remote-settings-popover-tmpl") + .tmpl({ + proxyConnectorsViewModel: self, + proxyConnector:ko.toJS(proxyConnector) + } ).html(); + + var targetImg = $(("#proxy-connectors-grid-remoterepo-settings-edit-") + +proxyConnector.sourceRepoId().replace(/\./g,"\\\.")+"-"+proxyConnector.targetRepoId().replace(/\./g,"\\\.")); + return tmplHtml; + } + + this.displaySettings=function(sourceRepoId,targetRepoId,targetContentStartId, targetImgStartId){ + var proxyConnector=getProxyConnector(sourceRepoId,targetRepoId); + showSettings(proxyConnector,targetContentStartId,targetImgStartId); + } + + this.findPolicyInformationName=function(id){ + for(var i=0;i<self.policyInformations().length;i++){ + if (id==self.policyInformations()[i].id()){ + return self.policyInformations()[i].name(); + } + } + return null; + } + + orderChangeAware=function(proxyConnector){ + return findProxyConnectorsWithSourceId(proxyConnector).length>1; + } + + findProxyConnectorsWithSourceId=function(proxyConnector){ + return $.grep(self.proxyConnectors(),function(curProxyConnector,idx){ + return curProxyConnector.sourceRepoId()==proxyConnector.sourceRepoId(); + } + ); + } + + displayOrderEdit=function(proxyConnector){ + var proxyConnectors=findProxyConnectorsWithSourceId(proxyConnector); + $.log("displayOrderEdit:"+proxyConnector.sourceRepoId()+",number:"+proxyConnectors.length); + + var managedRepository = getManagedRepository(proxyConnector.sourceRepoId()); + var proxyConnectorEditOrderViewModel=new ProxyConnectorEditOrderViewModel(proxyConnectors,self,managedRepository); + ko.applyBindings(proxyConnectorEditOrderViewModel,$("#main-content").find("#proxy-connector-edit-order").get(0)); + activateProxyConnectorsEditOrderTab(); + } + + this.displayGrid=function(){ + this.gridViewModel = new ko.simpleGrid.viewModel({ + data: self.proxyConnectors, + pageSize: 5, + gridUpdateCallBack: function(){ + $("#main-content" ).find("#proxyConnectorsTable" ).find("[title]").tooltip(); + } + }); + var mainContent = $("#main-content"); + + ko.applyBindings(this,mainContent.find("#proxy-connectors-view").get(0)); + var prxGrids=mainContent.find("[id^='proxy-connectors-grid-remoterepo-settings-edit-']"); + prxGrids.popover(); + removeSmallSpinnerImg(); + mainContent.find("#proxy-connectors-view-tabs #proxy-connectors-view-tabs-a-network-proxies-grid").tab('show'); + + mainContent.find("#proxy-connectors-view-tabs").on('show', function (e) { + $.log("on show:"+$(e.target).attr("href")); + if ($(e.target).attr("href")=="#proxy-connectors-edit") { + $.log("#proxy-connectors-edit"); + var proxyConnector=new ProxyConnector(); + var defaultPolicies=new Array(); + // populate with defaut policies options + for (i=0;i<self.policyInformations().length;i++){ + defaultPolicies.push(new Entry(self.policyInformations()[i].id(),self.policyInformations()[i].defaultOption)); + } + proxyConnector.policiesEntries(defaultPolicies); + var proxyConnectorViewModel=new ProxyConnectorViewModel(proxyConnector,false,self); + mainContent.find("#proxy-connectors-edit").html($("#proxy-connector-edit-form-tmpl").tmpl()); + ko.applyBindings(proxyConnectorViewModel,mainContent.find("#proxy-connectors-edit").get(0)); + mainContent.find("#sourceRepoId" ).select2(); + mainContent.find("#targetRepoId" ).select2(); + } + if ($(e.target).attr("href")=="#proxy-connectors-view") { + $("#proxy-connectors-view-tabs-a-network-proxies-grid").html($.i18n.prop("proxy-connectors.grid.tab.title")); + mainContent.find("#proxy-connectors-view-tabs-li-edit a").html($.i18n.prop("add")); + } + if ($(e.target).attr("href")=="#proxy-connectors-edit-order") { + activateProxyConnectorsEditOrderTab(); + } + + }); + } + + } + + ProxyConnectorEditOrderViewModel=function(proxyConnectors,proxyConnectorsViewModel,managedRepository){ + var self=this; + this.proxyConnectors=ko.observableArray(proxyConnectors); + this.proxyConnectorsViewModel=proxyConnectorsViewModel; + this.managedRepository=managedRepository; + proxyConnectorMoved=function(arg){ + $.log("proxyConnectorMoved:"+arg.sourceIndex+" to " + arg.targetIndex); + // if only 1 move just update two whereas update all with the new order + if (arg.targetIndex-arg.sourceIndex==1){ + self.proxyConnectors()[arg.targetIndex].order(arg.targetIndex+1); + self.proxyConnectors()[arg.sourceIndex].order(arg.sourceIndex+1); + } else { + for (i=0;i<self.proxyConnectors().length;i++){ + self.proxyConnectors()[i].order(i+1); + } + } + } + + this.findRemoteRepository=function(id){ + $.log("findRemoteRepository:"+id()); + for(var i=0;i<self.proxyConnectorsViewModel.remoteRepositories().length;i++){ + if (self.proxyConnectorsViewModel.remoteRepositories()[i].id()==id()){ + return self.proxyConnectorsViewModel.remoteRepositories()[i]; + } + } + return null; + } + + this.updateModifiedProxyConnectors=function(){ + self.proxyConnectorsViewModel.updateModifiedProxyConnectors(); + } + + displaySettings=function(sourceRepoId,targetRepoId){ + $.log("ProxyConnectorEditOrderViewModel#showSettings:"+sourceRepoId+"-"+targetRepoId); + self.proxyConnectorsViewModel.displaySettings(sourceRepoId,targetRepoId, + "#proxy-connectors-order-remoterepo-settings-content-", + "#proxy-connectors-order-remoterepo-settings-edit-"); + } + + } + + displayProxyConnectors=function(){ + screenChange(); + var mainContent = $("#main-content"); + mainContent.html($("#proxyConnectorsMain").tmpl()); + mainContent.append(smallSpinnerImg()); + + this.proxyConnectorsViewModel = new ProxyConnectorsViewModel(); + var self=this; + + loadManagedRepositories(function(data) { + self.proxyConnectorsViewModel.managedRepositories(mapManagedRepositories(data)); + + loadRemoteRepositories(function(data) { + self.proxyConnectorsViewModel.remoteRepositories(mapRemoteRepositories(data)); + + loadNetworkProxies(function(data) { + self.proxyConnectorsViewModel.networkProxies(mapNetworkProxies(data)); + + loadAllPolicies( function(data) { + self.proxyConnectorsViewModel.policyInformations(mapPolicyInformations(data)); + + loadAllProxyConnectors( function(data) { + self.proxyConnectorsViewModel.proxyConnectors(mapProxyConnectors(data)); + self.proxyConnectorsViewModel.displayGrid(); + }); + + }); + + }); + + }); + + }); + + } + + loadAllPolicies=function(successCallBackFn,errorCallBackFn){ + $.ajax("restServices/archivaServices/proxyConnectorService/allPolicies", { + type: "GET", + dataType: 'json', + success: successCallBackFn, + error: errorCallBackFn + } + ); + } + + loadAllProxyConnectors=function(successCallBackFn,errorCallBackFn){ + $.ajax("restServices/archivaServices/proxyConnectorService/getProxyConnectors", { + type: "GET", + dataType: 'json', + success: successCallBackFn, + error: errorCallBackFn + }); + } + + activateProxyConnectorsGridTab=function(){ + var mainContent = $("#main-content"); + mainContent.find("#proxy-connectors-view-tabs-content div[class*='tab-pane']").removeClass("active"); + mainContent.find("#proxy-connectors-view-tabs li").removeClass("active"); + + mainContent.find("#proxy-connectors-view").addClass("active"); + mainContent.find("#proxy-connectors-view-tabs-li-grid").addClass("active"); + mainContent.find("#proxy-connectors-view-tabs-li-edit a").html($.i18n.prop("add")); + + } + + activateProxyConnectorsEditTab=function(){ + var mainContent = $("#main-content"); + + mainContent.find("#proxy-connectors-view-tabs-content div[class*='tab-pane']").removeClass("active"); + mainContent.find("#proxy-connectors-view-tabs li").removeClass("active"); + + mainContent.find("#proxy-connectors-edit").addClass("active"); + mainContent.find("#proxy-connectors-view-tabs-li-edit").addClass("active"); + } + + activateProxyConnectorsEditOrderTab=function(){ + var mainContent = $("#main-content"); + + mainContent.find("#proxy-connectors-view-tabs-content div[class*='tab-pane']").removeClass("active"); + mainContent.find("#proxy-connectors-view-tabs li").removeClass("active"); + + mainContent.find("#proxy-connector-edit-order").addClass("active"); + mainContent.find("#proxy-connectors-view-tabs-li-edit-order").addClass("active"); + } + + mapProxyConnector=function(data){ + if (data==null){ + return null; + } + var policiesEntries = data.policiesEntries == null ? []: $.each(data.policiesEntries,function(item){ + return new Entry(item.key, item.value); + }); + if (!$.isArray(policiesEntries)){ + policiesEntries=[]; + } + var propertiesEntries = data.propertiesEntries == null ? []: $.each(data.propertiesEntries,function(item){ + return new Entry(item.key, item.value); + }); + if (!$.isArray(propertiesEntries)){ + propertiesEntries=[]; + } + return new ProxyConnector(data.sourceRepoId,data.targetRepoId,data.proxyId,mapStringArray(data.blackListPatterns), + mapStringArray(data.whiteListPatterns),policiesEntries,propertiesEntries, + data.disabled,data.order); + } + + mapProxyConnectors=function(data){ + var mappedProxyConnectors = $.map(data, function(item) { + return mapProxyConnector(item); + }); + return mappedProxyConnectors; + } + + mapPolicyInformation=function(data){ + if (data==null){ + return null; + } + var policyInformation = new PolicyInformation(mapStringArray(data.options),data.defaultOption,data.id,data.name); + $.log("policyInformation.options:"+policyInformation.options()); + return policyInformation; + } + + mapPolicyInformations=function(data){ + return $.map(data, function(item) { + return mapPolicyInformation(item); + }); + } + + removeProxyConnector=function(proxyConnector,fnSuccessCallback){ + clearUserMessages(); + var url="restServices/archivaServices/proxyConnectorService/removeProxyConnector?"; + url += "sourceRepoId="+encodeURIComponent(proxyConnector.sourceRepoId()); + url += "&targetRepoId="+encodeURIComponent(proxyConnector.targetRepoId()); + $.ajax(url, + { + type: "GET", + contentType: 'application/json', + success: function(data) { + fnSuccessCallback(); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + } + } + ); + + } + +}); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/repositories.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/repositories.js new file mode 100644 index 000000000..498cc95e9 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/repositories.js @@ -0,0 +1,1304 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +define("archiva.repositories",["jquery","i18n","jquery.tmpl","bootstrap","jquery.validate","knockout","knockout.simpleGrid"], +function(jquery,i18n,jqueryTmpl,bootstrap,jqueryValidate,ko) { + + // FIXME this must be dynamic if we do a plugin mechanism with dynamic repositories types + // FIXME i18n + + ManagedRepositoryType=function(type,label){ + this.type=type; + this.label=label; + } + + window.managedRepositoryTypes = [ + new ManagedRepositoryType("default","Maven 2.x Repository"), + new ManagedRepositoryType("legacy", "Maven 1.x Repository") + ]; + + ManagedRepository=function(id,name,layout,indexDirectory,location,snapshots,releases,blockRedeployments,cronExpression, + scanned,daysOlder,retentionCount,deleteReleasedSnapshots,stageRepoNeeded,description, + skipPackedIndexCreation,feedsUrl,url){ + + var self=this; + + //private String id; + this.id=ko.observable(id); + this.id.subscribe(function(newValue){self.modified(true)}); + + //private String name; + this.name=ko.observable(name); + this.name.subscribe(function(newValue){self.modified(true)}); + + //private String layout = "default"; + this.layout=ko.observable(layout); + this.layout.subscribe(function(newValue){self.modified(true)}); + + //private String indexDirectory; + this.indexDirectory=ko.observable(indexDirectory); + this.indexDirectory.subscribe(function(newValue){self.modified(true)}); + + //private String location; + this.location=ko.observable(location); + this.location.subscribe(function(newValue){self.modified(true)}); + + //private String cronExpression = "0 0 * * * ?"; + this.cronExpression=ko.observable(cronExpression); + this.cronExpression.subscribe(function(newValue){self.modified(true)}); + + //private ManagedRepository stagingRepository; + + //private int daysOlder = 100; + this.daysOlder=ko.observable(daysOlder); + this.daysOlder.subscribe(function(newValue){self.modified(true)}); + + //private int retentionCount = 2; + this.retentionCount=ko.observable(retentionCount); + this.retentionCount.subscribe(function(newValue){self.modified(true)}); + + //private boolean scanned = true; + this.scanned=ko.observable(scanned?scanned:true); + this.scanned.subscribe(function(newValue){self.modified(true)}); + + //private boolean deleteReleasedSnapshots; + this.deleteReleasedSnapshots=ko.observable(deleteReleasedSnapshots); + this.deleteReleasedSnapshots.subscribe(function(newValue){self.modified(true)}); + + //private boolean stageRepoNeeded; + this.stageRepoNeeded=ko.observable(stageRepoNeeded); + this.stageRepoNeeded.subscribe(function(newValue){self.modified(true)}); + + //private boolean snapshots = false; + this.snapshots=ko.observable(snapshots?snapshots:false); + this.snapshots.subscribe(function(newValue){self.modified(true)}); + + //private boolean releases = true; + this.releases=ko.observable(releases?releases:false); + this.releases.subscribe(function(newValue){self.modified(true)}); + + //private boolean blockRedeployments = false; + this.blockRedeployments=ko.observable(blockRedeployments?blockRedeployments:false); + this.blockRedeployments.subscribe(function(newValue){self.modified(true)}); + + //private String name; + this.description=ko.observable(description); + this.description.subscribe(function(newValue){self.modified(true)}); + + this.skipPackedIndexCreation=ko.observable(skipPackedIndexCreation?skipPackedIndexCreation:false); + this.skipPackedIndexCreation.subscribe(function(newValue){self.modified(true)}); + + this.feedsUrl=feedsUrl; + + this.url=url; + + this.getTypeLabel=function(){ + for(var i=0;i<window.managedRepositoryTypes.length;i++){ + if (window.managedRepositoryTypes[i].type==self.layout()){ + return window.managedRepositoryTypes[i].label; + } + } + return "no label"; + } + + this.modified=ko.observable(false); + } + + ArchivaRepositoryStatistics=function(scanEndTime,scanStartTime,totalArtifactCount,totalArtifactFileSize,totalFileCount, + totalGroupCount,totalProjectCount,newFileCount,duration,managedRepository,lastScanDate){ + //private Date scanEndTime; + this.scanEndTime = ko.observable(scanEndTime); + + //private Date scanStartTime; + this.scanStartTime = ko.observable(scanStartTime); + + //private long totalArtifactCount; + this.totalArtifactCount = ko.observable(totalArtifactCount); + + //private long totalArtifactFileSize; + this.totalArtifactFileSize = ko.observable(totalArtifactFileSize); + + //private long totalFileCount; + this.totalFileCount = ko.observable(totalFileCount); + + //private long totalGroupCount; + this.totalGroupCount = ko.observable(totalGroupCount); + + //private long totalProjectCount; + this.totalProjectCount = ko.observable(totalProjectCount); + + //private long newFileCount; + this.newFileCount = ko.observable(newFileCount); + + this.duration = ko.observable(duration); + + this.managedRepository = managedRepository; + + this.lastScanDate=ko.observable(lastScanDate); + } + + mapManagedRepositories=function(data,applicationUrl){ + var mappedManagedRepositories = $.map(data, function(item) { + var managedRepository = mapManagedRepository(item); + managedRepository.feedsUrl=applicationUrl+"/feeds/"+managedRepository.id(); + managedRepository.url=applicationUrl+"/repository/"+managedRepository.id() + return managedRepository; + }); + return mappedManagedRepositories; + } + mapManagedRepository=function(data){ + if (data==null){ + return null; + } + return new ManagedRepository(data.id,data.name,data.layout,data.indexDirectory,data.location,data.snapshots + ,data.releases, + data.blockRedeployments,data.cronExpression, + data.scanned,data.daysOlder,data.retentionCount,data.deleteReleasedSnapshots, + data.stageRepoNeeded,data.description,data.skipPackedIndexCreation); + } + + mapArchivaRepositoryStatistics=function(data){ + if (data==null){ + return null; + } + return new ArchivaRepositoryStatistics(data.scanEndTime,data.scanStartTime,data.totalArtifactCount,data.totalArtifactFileSize, + data.totalFileCount,data.totalGroupCount,data.totalProjectCount,data.newFileCount, + data.duration,data.managedRepository,data.lastScanDate) + } + + ManagedRepositoryViewModel=function(managedRepository, update, managedRepositoriesViewModel){ + this.managedRepository=managedRepository; + this.managedRepositoriesViewModel = managedRepositoriesViewModel; + this.update = update; + + var self = this; + + this.availableLayouts = window.managedRepositoryTypes; + + showCronExpressionDoc=function(){ + //$.log("showCronExpressionDoc") ; + } + + this.save=function(){ + $.log('managedrepo save'); + var valid = $("#main-content").find("#managed-repository-edit-form").valid(); + if (valid==false) { + return; + } + $.log("save:"+this.managedRepository.name()); + clearUserMessages(); + var userMessages=$("#user-messages"); + userMessages.html(mediumSpinnerImg()); + $("#managed-repository-save-button" ).button('loading'); + if (this.update){ + $.ajax("restServices/archivaServices/managedRepositoriesService/updateManagedRepository", + { + type: "POST", + data: ko.toJSON(this.managedRepository), + contentType: 'application/json', + dataType: 'json', + success: function(data) { + displaySuccessMessage($.i18n.prop('managedrepository.updated',self.managedRepository.id())); + activateManagedRepositoriesGridTab(); + self.managedRepository.modified(false); + }, + complete: function(){ + $("#managed-repository-save-button" ).button('reset'); + removeMediumSpinnerImg(userMessages); + } + } + ); + } else { + var url="restServices/archivaServices/managedRepositoriesService/fileLocationExists"; + url+="?fileLocation="+encodeURIComponent(self.managedRepository.location()); + $.ajax(url, + { + type: "GET", + dataType: 'json', + success: function(data) { + if (data){ + var completeCallbackFn = function(){window.modalConfirmDialog.modal('hide')}; + openDialogConfirm( + function(){addManagedRepository(self.managedRepository,completeCallbackFn)}, + $.i18n.prop('ok'), $.i18n.prop('cancel'), + $.i18n.prop('managedrepository.add.title'), + $("#managed-repository-location-warning-tmpl").tmpl(self.managedRepository)); + }else{ + addManagedRepository(self.managedRepository); + } + }, + complete: function(){ + $("#managed-repository-save-button" ).button('reset'); + removeMediumSpinnerImg(userMessages); + } + }); + } + } + + addManagedRepository=function(managedRepository,completeCallbackFn){ + var curManagedRepository=managedRepository; + var callbackFn = completeCallbackFn; + var dataJson=ko.toJSON(managedRepository); + $.log("managedRepository.release:"+managedRepository.releases()+",dataJson:"+dataJson); + $.ajax("restServices/archivaServices/managedRepositoriesService/addManagedRepository", + { + type: "POST", + contentType: 'application/json', + data: dataJson, + dataType: 'json', + success: function(data) { + if (managedRepository.stageRepoNeeded()){ + $.log("stageRepoNeeded:"+managedRepository.stageRepoNeeded()); + // reload all to see the new staged repo + loadManagedRepositories(function(data){ + self.managedRepositoriesViewModel.managedRepositories(mapManagedRepositories(data)); + }); + } else { + curManagedRepository.location(data.location); + self.managedRepositoriesViewModel.managedRepositories.push(curManagedRepository); + } + + displaySuccessMessage($.i18n.prop('managedrepository.added',curManagedRepository.id())); + curManagedRepository.modified(false); + activateManagedRepositoriesGridTab(); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + }, + complete:function(data){ + if(callbackFn){ + callbackFn(); + } + } + } + ); + } + + displayGrid=function(){ + activateManagedRepositoriesGridTab(); + } + + } + + activateManagedRepositoryFormValidation=function(){ + var validator = $("#main-content" ).find("#managed-repository-edit-form").validate({ + rules: { + daysOlder : { + digits: true, + min: 1 + }, + retentionCount : { + digits: true, + min: 1, + max: 100 + }, + cronExpression: { + required: true, + remote: { + url: "restServices/archivaServices/commonServices/validateCronExpression", + type: "get" + } + }, + id: { + required: true, + remote: { + url: "restServices/archivaUiServices/dataValidatorService/managedRepositoryIdNotExists", + type: "get" + } + } + }, + showErrors: function(validator, errorMap, errorList) { + customShowError("#main-content #managed-repository-edit-form",validator,errorMap,errorMap); + } + }); + validator.settings.messages["cronExpression"]=$.i18n.prop("cronExpression.notvalid"); + validator.settings.messages["id"]=$.i18n.prop("id.required.or.alreadyexists"); + } + + ManagedRepositoriesViewModel=function(){ + this.managedRepositories=ko.observableArray([]); + + this.gridViewModel = null; + var self = this; + + editManagedRepository=function(managedRepository){ + var mainContent = $("#main-content"); + var viewModel = new ManagedRepositoryViewModel(managedRepository,true,self); + ko.applyBindings(viewModel,mainContent.find("#managed-repository-edit").get(0)); + activateManagedRepositoryEditTab(); + mainContent.find("#managed-repository-edit-li a").html($.i18n.prop('edit')); + activateManagedRepositoryFormValidation(); + activatePopoverDoc(); + } + + this.editManagedRepositoryWithId=function(managedRepositoryId){ + $.each(self.managedRepositories(), function(index, value) { + if(value.id()==managedRepositoryId){ + editManagedRepository(value); + } + }); + } + + scanNow=function(managedRepository){ + clearUserMessages(); + openDialogConfirm( + function(){ + $("#dialog-confirm-modal" ).find("#modal-login-footer").append(smallSpinnerImg()); + var checked = $("#managed-repository-scan-now-all").get(0).checked; + var url = "restServices/archivaServices/repositoriesService/scanRepositoryNow?"; + url += "repositoryId="+encodeURIComponent(managedRepository.id()); + url += "&fullScan="+(checked==true?"true":"false"); + $.ajax(url, + { + type: "GET", + beforeSend:function(){ + displayInfoMessage($.i18n.prop("managedrepository.scan.started",managedRepository.id())); + closeDialogConfirm(); + }, + success: function(data) { + displaySuccessMessage($.i18n.prop("managedrepository.scanned",managedRepository.name())); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + }, + complete: function(){ + removeSmallSpinnerImg(); + closeDialogConfirm(); + } + } + ); + }, + $.i18n.prop("ok"), + $.i18n.prop("cancel"), + $.i18n.prop("managedrepository.scan.now"), + $("#managed-repository-scan-now-modal-tmpl").tmpl(managedRepository)); + + } + + removeManagedRepository=function(managedRepository){ + clearUserMessages(); + openDialogConfirm( + function(){ + var url = "restServices/archivaServices/managedRepositoriesService/deleteManagedRepository?"; + url += "repositoryId="+encodeURIComponent(managedRepository.id()); + var checked = $("#managedrepository-deletecontent").get(0).checked; + url += "&deleteContent="+(checked==true?"true":"false"); + var dialogText=$("#dialog-confirm-modal-body-text" ); + dialogText.html(mediumSpinnerImg()); + $.ajax(url, + { + type: "GET", + success: function(data) { + self.managedRepositories.remove(managedRepository); + displaySuccessMessage($.i18n.prop("managedrepository.deleted",managedRepository.name())); + + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + }, + complete: function(){ + removeMediumSpinnerImg(dialogText); + closeDialogConfirm(); + } + } + ); + + }, + $.i18n.prop("ok"), + $.i18n.prop("cancel"), + $.i18n.prop("managedrepository.delete.confirm",managedRepository.name()), + $("#managed-repository-delete-warning-tmpl").tmpl(managedRepository)); + } + + updateManagedRepository=function(managedRepository){ + var managedRepositoryViewModel = new ManagedRepositoryViewModel(managedRepository,true,this); + managedRepositoryViewModel.save(); + } + + this.bulkSave=function(){ + $.log("bulkSave"); + return getModifiedManagedRepositories().length>0; + } + + getModifiedManagedRepositories=function(){ + var prx = $.grep(self.managedRepositories(), + function (managedRepository,i) { + return managedRepository.modified(); + }); + return prx; + } + updateModifiedManagedRepositories=function(){ + var repos = getModifiedManagedRepositories(); + + openDialogConfirm(function(){ + for (i=0;i<repos.length;i++){ + updateManagedRepository(repos[i]); + } + closeDialogConfirm(); + }, + $.i18n.prop('ok'), + $.i18n.prop('cancel'), + $.i18n.prop('managed.repository.bulk.save.confirm.title'), + $.i18n.prop('managed.repository.bulk.save.confirm',repos.length)); + } + + directoriesScan=function(managedRepository){ + $.log("directoriesScan:"+managedRepository.id()); + clearUserMessages(); + var url = "restServices/archivaServices/repositoriesService/scanRepositoryDirectoriesNow/"+managedRepository.id(); + $.ajax(url, + { + type: "GET", + dataType: 'json', + beforeSend:function(){ + displayInfoMessage($.i18n.prop("managedrepository.scan.directories.started", managedRepository.id())); + }, + success: function(data) { + $.log(" scanRepositoryDirectoriesNow finished "); + displaySuccessMessage( $.i18n.prop("managedrepository.scan.directories.finished", managedRepository.id())); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + }, + complete: function(){ + removeSmallSpinnerImg(); + } + + } + ); + } + + showStats=function(managedRepository){ + if ($(calculatePopoverId(managedRepository)).html()){ + // we ask stats all the time ? if no uncomment return + //return; + $("#managedrepository-stats-"+escapeDot(managedRepository.id())).append(smallSpinnerImg()); + } + var curRepo=managedRepository; + var url = "restServices/archivaServices/managedRepositoriesService/getManagedRepositoryStatistics/"+managedRepository.id(); + url+="/"+encodeURIComponent(usedLang()); + $.ajax(url, + { + type: "GET", + dataType: 'json', + success: function(data) { + if (data==null){ + return; + } + var archivaRepositoryStatistics=mapArchivaRepositoryStatistics(data); + archivaRepositoryStatistics.managedRepository=curRepo; + var mainContent = $("#main-content"); + mainContent.find("#managedrepository-stats-"+escapeDot(curRepo.id())).append($("#managed-repository-stats-tmpl").tmpl(archivaRepositoryStatistics)); + mainContent.find("#managedrepository-stats-img-"+escapeDot(curRepo.id())).attr("data-content",$(calculatePopoverId(curRepo)).html()); + mainContent.find("#managedrepository-stats-img-"+escapeDot(curRepo.id())).popover( + { + placement: "left", + html: true, + trigger:'manual' + } + ); + + mainContent.find("#managedrepository-stats-img-"+escapeDot(curRepo.id())).popover('show'); + removeSmallSpinnerImg(); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + }, + complete: function(){ + } + } + ); + } + + calculatePopoverId=function(managedRepository){ + return "#main-content #managedrepository-stats-"+escapeDot(managedRepository.id()) + " #managedrepository-stats-"+escapeDot(managedRepository.id())+"-popover"; + } + + hideStats=function(managedRepository){ + $("#body_content" ).find(".popover" ).hide(); + } + + showPomSnippet=function(managedRepository){ + var mainContent = $("#main-content"); + mainContent.find("#managed-repositories-pom-snippet").html(mediumSpinnerImg()); + mainContent.find('#managed-repositories-pom-snippet').show(); + var url = "restServices/archivaServices/managedRepositoriesService/getPomSnippet/"+encodeURIComponent(managedRepository.id()); + $.ajax(url, + { + type: "GET", + dataType: 'text', + success: function(data) { + $("#managed-repositories-pom-snippet").html($("#pom-snippet-tmpl").tmpl(data)); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + }, + complete: function(){ + } + } + ); + + } + + mergeRepo=function(managedRepository){ + var userMessages=$("#user-messages"); + userMessages.html(mediumSpinnerImg()); + // is there any artifacts to merge ? + var artifactsNumberUrl = "restServices/archivaServices/browseService/artifacts/"+encodeURIComponent(managedRepository.id()); + $.ajax(artifactsNumberUrl,{ + type: "GET", + dataType: 'json', + success: function(data){ + var artifacts=mapArtifacts(data); + $.log("artifactsNumber for '" + managedRepository.id() + "': " + artifacts.length); + + if (artifacts<1){ + displayWarningMessage($.i18n.prop("managedrepository.merge.noartifacts", managedRepository.id())); + return; + } + + $.log("merge repo open dialog"); + var dialogMergeRepo=$("#dialog-modal-merge-repo"); + if (window.modalMergeRepoDialog==null) { + window.modalMergeRepoDialog = dialogMergeRepo.modal(); + + } + + loadManagedRepositories(function(data){ + + var managedRepositories = $.map(mapManagedRepositories(data), function(item) { + return item.id()==managedRepository.id()?null:item; + }); + $("#dialog-modal-merge-repo-body-text").html($("#merge-repo-dialog-content" ) + .tmpl({sourceRepoId:managedRepository.id(),repositories:managedRepositories})); + window.modalMergeRepoDialog.modal('show'); + }); + + }, + complete: function(){ + removeMediumSpinnerImg(userMessages); + } + } + ); + + } + + + } + + + mergeRepositories=function(sourceRepository,targetRepository){ + $.log("mergeRepositories:"+sourceRepository+":"+targetRepository); + + var mergeRepoDialogBodyId="dialog-modal-merge-repo-body-text"; + var mergeRepoDialogBody=$("#"+mergeRepoDialogBodyId); + mergeRepoDialogBody.html(mediumSpinnerImg()); + + // check conflicts + var url = "restServices/archivaServices/mergeRepositoriesService/mergeConflictedArtifacts/"+encodeURIComponent(sourceRepository); + url+="/"+encodeURIComponent(targetRepository); + $.ajax(url, { + type: "GET", + dataType: 'json', + success: function(data){ + var artifacts=mapArtifacts(data); + if (artifacts && artifacts.length){ + // we have conflicts ask to skip or not + $.log("conflicts:"+artifacts.length); + displayWarningMessage($.i18n.prop("managedrepository.merge.conflicts", artifacts.length),"dialog-modal-merge-repo-body-text"); + $.tmpl($("#merge-repo-skip-conflicts").html(), + { artifacts:artifacts, sourceRepository: sourceRepository, targetRepository:targetRepository }) + .appendTo( "#dialog-modal-merge-repo-body-text" ); + $("#dialog-modal-merge-repo-header-title" ).html($.i18n.prop("managedrepository.merge.conflicts.header",sourceRepository,targetRepository)); + } else { + doMerge(sourceRepository,targetRepository,false); + } + }, + complete: function(){ + $.log("complete removeMediumSpinnerImg"); + removeMediumSpinnerImg("#dialog-modal-merge-repo-body-text"); + } + }); + + + + } + + doMerge=function(sourceRepository,targetRepository,skipConflicts){ + $.log("doMerge:"+sourceRepository+" to " + targetRepository + ", skipConflicts: " + skipConflicts); + window.modalMergeRepoDialog.modal('hide'); + var userMessages=$("#user-messages"); + userMessages.html(mediumSpinnerImg()); + var url = "restServices/archivaServices/mergeRepositoriesService/mergeRepositories/"+encodeURIComponent(sourceRepository); + url+="/"+encodeURIComponent(targetRepository); + url+="/"+skipConflicts; + $.ajax(url, { + type: "GET", + dataType: 'json', + success: function(data){ + displaySuccessMessage($.i18n.prop("managedrepository.merge.success", sourceRepository,targetRepository)); + }, + complete: function(){ + removeMediumSpinnerImg(userMessages); + } + }); + } + + activateManagedRepositoriesGridTab=function(){ + var mainContent = $("#main-content"); + mainContent.find("#managed-repository-edit-li").removeClass("active"); + mainContent.find("#managed-repository-edit").removeClass("active"); + + mainContent.find("#managed-repositories-view-li").addClass("active"); + mainContent.find("#managed-repositories-view").addClass("active"); + mainContent.find("#managed-repository-edit-li a").html($.i18n.prop("add")); + } + + activateManagedRepositoryEditTab=function(){ + var mainContent = $("#main-content"); + mainContent.find("#managed-repositories-view-li").removeClass("active"); + mainContent.find("#managed-repositories-view").removeClass("active"); + + mainContent.find("#managed-repository-edit-li").addClass("active"); + mainContent.find("#managed-repository-edit").addClass("active"); + } + + + //--------------------------- + // Remote repositories part + //--------------------------- + + + + RemoteRepository=function(id,name,layout,indexDirectory,url,userName,password,timeout,downloadRemoteIndex,remoteIndexUrl, + remoteDownloadNetworkProxyId,cronExpression,remoteDownloadTimeout,downloadRemoteIndexOnStartup, + description,extraParametersEntries,extraHeadersEntries){ + + var self=this; + + //private String id; + this.id=ko.observable(id); + this.id.subscribe(function(newValue){self.modified(true)}); + + //private String name; + this.name=ko.observable(name); + this.name.subscribe(function(newValue){self.modified(true)}); + + //private String layout = "default"; + this.layout=ko.observable(layout); + this.layout.subscribe(function(newValue){self.modified(true)}); + + //private String indexDirectory; + this.indexDirectory=ko.observable(indexDirectory); + this.indexDirectory.subscribe(function(newValue){self.modified(true)}); + + //private String url; + this.url=ko.observable(url); + this.url.subscribe(function(newValue){self.modified(true)}); + + //private String userName; + this.userName=ko.observable(userName); + this.userName.subscribe(function(newValue){self.modified(true)}); + + //private String password; + this.password=ko.observable(password); + this.password.subscribe(function(newValue){self.modified(true)}); + + //private int timeout = 60; + this.timeout=ko.observable(timeout); + this.timeout.subscribe(function(newValue){self.modified(true)}); + + //private boolean downloadRemoteIndex = false; + this.downloadRemoteIndex=ko.observable(downloadRemoteIndex?false:downloadRemoteIndex); + this.downloadRemoteIndex.subscribe(function(newValue){self.modified(true)}); + + //private String remoteIndexUrl = ".index"; + this.remoteIndexUrl=ko.observable(remoteIndexUrl); + this.remoteIndexUrl.subscribe(function(newValue){self.modified(true)}); + + //private String remoteDownloadNetworkProxyId; + this.remoteDownloadNetworkProxyId=ko.observable(remoteDownloadNetworkProxyId); + this.remoteDownloadNetworkProxyId.subscribe(function(newValue){self.modified(true)}); + + //private String cronExpression = "0 0 08 ? * SUN"; + this.cronExpression=ko.observable(cronExpression); + this.cronExpression.subscribe(function(newValue){self.modified(true)}); + + //private int remoteDownloadTimeout = 300; + this.remoteDownloadTimeout=ko.observable(remoteDownloadTimeout); + this.remoteDownloadTimeout.subscribe(function(newValue){self.modified(true)}); + + //private boolean downloadRemoteIndexOnStartup = false; + this.downloadRemoteIndexOnStartup=ko.observable(downloadRemoteIndexOnStartup?false:downloadRemoteIndexOnStartup); + this.downloadRemoteIndexOnStartup.subscribe(function(newValue){self.modified(true)}); + + this.description=ko.observable(description); + this.description.subscribe(function(newValue){self.modified(true)}); + + this.getTypeLabel=function(){ + for(var i=0;i<window.managedRepositoryTypes.length;i++){ + if (window.managedRepositoryTypes[i].type==self.layout()){ + return window.managedRepositoryTypes[i].label; + } + } + return "no label"; + } + + this.extraParametersEntries=ko.observableArray(extraParametersEntries==null?new Array():extraParametersEntries); + this.extraParametersEntries.subscribe(function(newValue){ + self.modified(true); + }); + + this.extraHeadersEntries=ko.observableArray(extraHeadersEntries==null?new Array():extraHeadersEntries); + this.extraHeadersEntries.subscribe(function(newValue){ + self.modified(true); + }); + + this.modified=ko.observable(false); + } + + mapRemoteRepository=function(data){ + if (data==null){ + return null; + } + + var extraParametersEntries = data.extraParametersEntries == null ? []: $.each(data.extraParametersEntries,function(item){ + return new Entry(item.key, item.value); + }); + if (!$.isArray(extraParametersEntries)){ + extraParametersEntries=[]; + } + + var extraHeadersEntries = data.extraHeadersEntries == null ? []: $.each(data.extraHeadersEntries,function(item){ + return new Entry(item.key, item.value); + }); + if (!$.isArray(extraHeadersEntries)){ + extraHeadersEntries=[]; + } + + return new RemoteRepository(data.id,data.name,data.layout,data.indexDirectory,data.url,data.userName,data.password, + data.timeout,data.downloadRemoteIndex,data.remoteIndexUrl,data.remoteDownloadNetworkProxyId, + data.cronExpression,data.remoteDownloadTimeout,data.downloadRemoteIndexOnStartup,data.description, + extraParametersEntries,extraHeadersEntries); + } + + mapRemoteRepositories=function(data){ + var mappedRemoteRepositories = $.map(data, function(item) { + return mapRemoteRepository(item); + }); + return mappedRemoteRepositories; + } + + RemoteRepositoryViewModel=function(remoteRepository, update, remoteRepositoriesViewModel){ + this.remoteRepository=remoteRepository; + this.remoteRepositoriesViewModel = remoteRepositoriesViewModel; + this.networkProxies=ko.observableArray([]); + this.update = update; + + var self = this; + + this.availableLayouts = window.managedRepositoryTypes; + + this.save=function(){ + var valid = $("#main-content" ).find("#remote-repository-edit-form").valid(); + if (valid==false) { + return; + } + clearUserMessages(); + var userMessages=$("#user-messages"); + userMessages.html(mediumSpinnerImg()); + $("#remote-repository-save-button" ).button('loading'); + if (update){ + $.ajax("restServices/archivaServices/remoteRepositoriesService/updateRemoteRepository", + { + type: "POST", + data: ko.toJSON(this.remoteRepository), + contentType: 'application/json', + dataType: 'json', + success: function(data) { + displaySuccessMessage($.i18n.prop('remoterepository.updated',self.remoteRepository.id())); + activateRemoteRepositoriesGridTab(); + self.remoteRepository.modified(false); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + }, + complete: function(){ + $("#remote-repository-save-button" ).button('reset'); + removeMediumSpinnerImg(userMessages); + } + } + ); + }else { + $.ajax("restServices/archivaServices/remoteRepositoriesService/addRemoteRepository", + { + type: "POST", + data: ko.toJSON(this.remoteRepository), + contentType: 'application/json', + dataType: 'json', + success: function(data) { + self.remoteRepository.modified(false); + self.remoteRepositoriesViewModel.remoteRepositories.push(self.remoteRepository); + displaySuccessMessage($.i18n.prop('remoterepository.added')); + activateRemoteRepositoriesGridTab(); + removeMediumSpinnerImg(userMessages); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + } + } + ); + } + } + + displayGrid=function(){ + activateRemoteRepositoriesGridTab(); + } + + addExtraParameter=function(){ + + var mainContent=$("#main-content"); + mainContent.find("#extra-parameters-error" ).empty(); + var key=mainContent.find("#extraParameter-key").val(); + if($.trim(key).length<1){ + displayErrorMessage( $.i18n.prop("key.empty.error.message"),"extra-parameters-error"); + return; + } + var value=mainContent.find("#extraParameter-value").val(); + $.log("addExtraParameter="+key+":"+value); + var oldTab = self.remoteRepository.extraParametersEntries(); + oldTab.push(new Entry(key,value)); + self.remoteRepository.extraParametersEntries(oldTab); + mainContent.find("#extraParameter-key").val(""); + mainContent.find("#extraParameter-value").val(""); + self.remoteRepository.modified(true); + } + + deleteExtraParameter=function(key){ + for(var i=0;i<self.remoteRepository.extraParametersEntries().length;i++){ + var entry=self.remoteRepository.extraParametersEntries()[i]; + if (entry.key==key){ + self.remoteRepository.extraParametersEntries.remove(entry); + self.remoteRepository.modified(true); + } + } + } + + addExtraHeader=function(){ + + var mainContent=$("#main-content"); + mainContent.find("#extra-headers-error" ).empty(); + var key=mainContent.find("#extraHeader-key").val(); + if( $.trim(key).length<1){ + if($.trim(key).length<1){ + displayErrorMessage( $.i18n.prop("key.empty.error.message"),"extra-headers-error"); + return; + } + } + var value=mainContent.find("#extraHeader-value").val(); + $.log("addExtraParameter="+key+":"+value); + var oldTab = self.remoteRepository.extraHeadersEntries(); + oldTab.push(new Entry(key,value)); + self.remoteRepository.extraHeadersEntries(oldTab); + mainContent.find("#extraHeader-key").val(""); + mainContent.find("#extraHeader-value").val(""); + self.remoteRepository.modified(true); + } + + deleteExtraHeader=function(key){ + for(var i=0;i<self.remoteRepository.extraHeadersEntries().length;i++){ + var entry=self.remoteRepository.extraHeadersEntries()[i]; + if (entry.key==key){ + self.remoteRepository.extraHeadersEntries.remove(entry); + self.remoteRepository.modified(true); + } + } + } + + } + + RemoteRepositoriesViewModel=function(){ + this.remoteRepositories=ko.observableArray([]); + this.applicationUrl=null; + this.gridViewModel = null; + var self = this; + + editRemoteRepository=function(remoteRepository){ + $.log("editRemoteRepository"); + $.ajax("restServices/archivaServices/networkProxyService/getNetworkProxies", { + type: "GET", + dataType: 'json', + success: function(data) { + var viewModel = new RemoteRepositoryViewModel(remoteRepository,true,self); + viewModel.networkProxies(mapNetworkProxies(data)); + var mainContent = $("#main-content"); + + ko.applyBindings(viewModel,mainContent.find("#remote-repository-edit").get(0)); + activateRemoteRepositoryEditTab(); + mainContent.find("#remote-repository-edit-li a").html($.i18n.prop('edit')); + activateRemoteRepositoryFormValidation(false); + activatePopoverDoc(); + } + }) + + } + + removeRemoteRepository=function(remoteRepository){ + clearUserMessages(); + openDialogConfirm( + function(){ + var dialogText=$("#dialog-confirm-modal-body-text" ); + dialogText.html(mediumSpinnerImg()); + $.ajax("restServices/archivaServices/remoteRepositoriesService/deleteRemoteRepository/"+encodeURIComponent(remoteRepository.id()), + { + type: "GET", + success: function(data) { + self.remoteRepositories.remove(remoteRepository); + displaySuccessMessage($.i18n.prop('remoterepository.deleted',remoteRepository.id())); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + }, + complete:function(){ + removeMediumSpinnerImg(dialogText); + closeDialogConfirm(); + } + } + )}, $.i18n.prop('ok'), + $.i18n.prop('cancel'), + $.i18n.prop('remoterepository.delete.confirm',remoteRepository.id()), + $("#remote-repository-delete-modal-tmpl").tmpl(remoteRepository)); + + } + + this.bulkSave=function(){ + return getModifiedRemoteRepositories().length>0; + } + + getModifiedRemoteRepositories=function(){ + var prx = $.grep(self.remoteRepositories(), + function (remoteRepository,i) { + return remoteRepository.modified(); + }); + return prx; + } + + updateModifiedRemoteRepositories=function(){ + var modifiedRemoteRepositories = getModifiedRemoteRepositories(); + + openDialogConfirm(function(){ + for(var i=0;i<modifiedRemoteRepositories.length;i++){ + updateRemoteRepository(modifiedRemoteRepositories[i]); + } + closeDialogConfirm(); + }, + $.i18n.prop('ok'), + $.i18n.prop('cancel'), + $.i18n.prop('remoterepositories.bulk.save.confirm.title'), + $.i18n.prop('remoterepositories.bulk.save.confirm',modifiedRemoteRepositories.length)); + } + + updateRemoteRepository=function(remoteRepository){ + var viewModel = new RemoteRepositoryViewModel(remoteRepository,true,self); + viewModel.save(); + } + + scheduleDownloadRemoteIndex=function(remoteRepository){ + openDialogConfirm( + function(){ + + var url = "restServices/archivaServices/repositoriesService/scheduleDownloadRemoteIndex?"; + url += "repositoryId="+encodeURIComponent(remoteRepository.id()); + + var now = $("#remoterepository-scan-now").get(0).checked; + + var full = $("#remoterepository-scan-full").get(0).checked; + + url += "&now="+(now==true?"true":"false"); + url += "&fullDownload="+(full==true?"true":"false"); + $.ajax(url, + { + type: "GET", + success: function(data) { + clearUserMessages(); + displaySuccessMessage($.i18n.prop("remoterepository.download.remote.scheduled",remoteRepository.name())); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + }, + complete: function(){ + closeDialogConfirm(); + } + } + ); + + }, + $.i18n.prop("ok"), + $.i18n.prop("cancel"), + $.i18n.prop("remoterepository.download.remote.confirm",remoteRepository.name()), + $("#remote-repository-scan-modal-tmpl").tmpl(remoteRepository)); + } + } + + /** + * + * @param validateId to validate if id already exists: not needed for update ! + */ + activateRemoteRepositoryFormValidation=function(validateId){ + // FIXME find a way to activate cronExpression validation only if downloadRemote is activated ! + var validator = null; + if (validateId){ + validator = $("#main-content" ).find("#remote-repository-edit-form").validate({ + rules: { + id: { + required: true, + remote: { + url: "restServices/archivaUiServices/dataValidatorService/remoteRepositoryIdNotExists", + type: "get" + } + } + }, + showErrors: function(validator, errorMap, errorList) { + customShowError("#main-content #remote-repository-edit-form",validator,errorMap,errorMap); + } + }); + } else { + validator = $("#main-content" ).find("#remote-repository-edit-form").validate({ + rules: { + id: { + required: true + } + }, + showErrors: function(validator, errorMap, errorList) { + customShowError("#main-content #remote-repository-edit-form",validator,errorMap,errorMap); + } + }); + } + validator.settings.messages["cronExpression"]=$.i18n.prop("cronExpression.notvalid"); + validator.settings.messages["id"]=$.i18n.prop("id.required.or.alreadyexists"); + } + + activateRemoteRepositoriesGridTab=function(){ + var mainContent = $("#main-content"); + mainContent.find("#remote-repository-edit-li").removeClass("active"); + mainContent.find("#remote-repository-edit").removeClass("active"); + + mainContent.find("#remote-repositories-view-li").addClass("active"); + mainContent.find("#remote-repositories-view").addClass("active"); + mainContent.find("#remote-repository-edit-li a").html($.i18n.prop("add")); + } + + activateRemoteRepositoryEditTab=function(){ + var mainContent = $("#main-content"); + mainContent.find("#remote-repositories-view-li").removeClass("active"); + mainContent.find("#remote-repositories-view").removeClass("active"); + + mainContent.find("#remote-repository-edit-li").addClass("active"); + mainContent.find("#remote-repository-edit").addClass("active"); + } + + //--------------------------- + // Screen loading + //--------------------------- + + /** + * + * @param successFnManagedRepositories function called with param managedRepositoriesViewModel when managed repositories grid has been displayed + * @param successFnRemoteRepositories function called with param remoteRepositoriesViewModel when remote repositories grid has been displayed + */ + displayRepositoriesGrid=function(successFnManagedRepositories,successFnRemoteRepositories){ + screenChange(); + var mainContent = $("#main-content"); + mainContent.html(mediumSpinnerImg()); + mainContent.html($("#repositoriesMain").tmpl()); + mainContent.find("#repositories-tabs a:first").tab("show"); + + mainContent.find("#managed-repositories-content").append(mediumSpinnerImg()); + mainContent.find("#remote-repositories-content").append(mediumSpinnerImg()); + + var managedRepositoriesViewModel = new ManagedRepositoriesViewModel(); + var remoteRepositoriesViewModel = new RemoteRepositoriesViewModel(); + + $.ajax({ + url: "restServices/archivaServices/archivaAdministrationService/applicationUrl", + type: "GET", + dataType: 'text', + success: function(applicationUrl){ + $.log("applicationUrl:"+applicationUrl); + loadManagedRepositories(function(data) { + + + managedRepositoriesViewModel.managedRepositories( + mapManagedRepositories(data,applicationUrl?applicationUrl:window.location.toString().substringBeforeLast("/"))); + + managedRepositoriesViewModel.gridViewModel = new ko.simpleGrid.viewModel({ + data: managedRepositoriesViewModel.managedRepositories, + columns: [ + { + headerText: $.i18n.prop('identifier'), + rowText: "id" + }, + { + headerText: $.i18n.prop('name'), + rowText: "name" + }, + { + headerText: $.i18n.prop('type'), + rowText: "getTypeLabel", + // FIXME i18n + title: "Repository type (default is Maven 2)" + } + ], + pageSize: 5, + gridUpdateCallBack: function(){ + // a bit ugly + //$("#main-content" ).find("#managed-repositories-table").find("[title]").tooltip({animation:"false"}); + } + }); + var mainContent = $("#main-content"); + ko.applyBindings(managedRepositoriesViewModel,mainContent.find("#managed-repositories-view").get(0)); + activatePopoverDoc(); + mainContent.find("#managed-repositories-pills #managed-repositories-view-a").tab('show'); + removeMediumSpinnerImg(mainContent.find("#managed-repositories-content")); + activateManagedRepositoriesGridTab(); + if(successFnManagedRepositories){ + successFnManagedRepositories(managedRepositoriesViewModel); + } + }); + + loadRemoteRepositories(function(data) { + remoteRepositoriesViewModel.remoteRepositories(mapRemoteRepositories(data)); + remoteRepositoriesViewModel.gridViewModel = new ko.simpleGrid.viewModel({ + data: remoteRepositoriesViewModel.remoteRepositories, + columns: [ + { + headerText: $.i18n.prop('identifier'), + rowText: "id" + }, + { + headerText: $.i18n.prop('name'), + rowText: "name" + }, + { + headerText: $.i18n.prop('url'), + rowText: "url" + }, + { + headerText: $.i18n.prop('type'), + rowText: "getTypeLabel", + // FIXME i18n + title: "Repository type (default is Maven 2)" + } + ], + pageSize: 5, + gridUpdateCallBack: function(){ + //$("#main-content" ).find("#remote-repositories-table").find("[title]").tooltip(); + } + }); + var mainContent = $("#main-content"); + ko.applyBindings(remoteRepositoriesViewModel,mainContent.find("#remote-repositories-view").get(0)); + mainContent.find("#remote-repositories-pills #remote-repositories-view-a").tab('show') + removeMediumSpinnerImg(mainContent.find("#remote-repositories-content")); + activatePopoverDoc(); + if(successFnRemoteRepositories){ + successFnRemoteRepositories(managedRepositoriesViewModel); + } + }); + } + } + ); + + + mainContent.find("#managed-repositories-pills").on('show', function (e) { + var mainContent = $("#main-content"); + if ($(e.target).attr("href")=="#managed-repository-edit") { + var managedRepo=new ManagedRepository(); + managedRepo.cronExpression("0 0 * * * ?"); + var viewModel = new ManagedRepositoryViewModel(managedRepo,false,managedRepositoriesViewModel); + ko.applyBindings(viewModel,mainContent.find("#managed-repository-edit").get(0)); + activateManagedRepositoryFormValidation(); + activatePopoverDoc(); + } + if ($(e.target).attr("href")=="#managed-repositories-view") { + mainContent.find("#managed-repository-edit-li a").html($.i18n.prop("add")); + } + + }); + + mainContent.find("#remote-repositories-pills").on('show', function (e) { + if ($(e.target).attr("href")=="#remote-repository-edit") { + $.ajax("restServices/archivaServices/networkProxyService/getNetworkProxies", { + type: "GET", + dataType: 'json', + success: function(data) { + var remoteRepo=new RemoteRepository(); + remoteRepo.cronExpression("0 0 08 ? * SUN"); + var viewModel = new RemoteRepositoryViewModel(remoteRepo,false,remoteRepositoriesViewModel); + viewModel.networkProxies(mapNetworkProxies(data)); + ko.applyBindings(viewModel,mainContent.find("#remote-repository-edit").get(0)); + activateRemoteRepositoryFormValidation(true); + activatePopoverDoc(); + } + }) + } + if ($(e.target).attr("href")=="#remote-repositories-view") { + $("#main-content" ).find("#remote-repository-edit-li" ).find("a").html($.i18n.prop("add")); + } + + }); + + } + + loadManagedRepositories=function(successCallBackFn,errorCallBackFn){ + $.ajax("restServices/archivaServices/managedRepositoriesService/getManagedRepositories", { + type: "GET", + dataType: 'json', + success: successCallBackFn, + error: errorCallBackFn + }); + } + + loadRemoteRepositories=function(successCallBackFn,errorCallBackFn){ + $.ajax("restServices/archivaServices/remoteRepositoriesService/getRemoteRepositories", { + type: "GET", + dataType: 'json', + success: successCallBackFn, + error: errorCallBackFn + }); + } + + findManagedRepository=function(id,managedRepositories){ + var managedRepository=$.grep(managedRepositories, + function(repo,idx){ + return repo.id()==id; + } + ); + return ($.isArray(managedRepository) && managedRepository.length>0) ? managedRepository[0]:new ManagedRepository(); + } + +});
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/repository-groups.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/repository-groups.js new file mode 100644 index 000000000..98cdd9323 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/repository-groups.js @@ -0,0 +1,385 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +define("archiva.repository-groups",["jquery","i18n","jquery.tmpl","bootstrap","jquery.validate","jquery.ui","knockout" + ,"knockout.simpleGrid","knockout.sortable"], +function(jquery,i18n,jqueryTmpl,bootstrap,jqueryValidate,jqueryUi,ko) { + + RepositoryGroup=function(id,repositories){ + + var self=this; + + //private String id; + this.id=ko.observable(id); + this.id.subscribe(function(newValue){self.modified(true)}); + + // private List<String> repositories; + this.repositories=ko.observableArray(repositories); + this.repositories.subscribe(function(newValue){self.modified(true)}); + + // to store managedRepositories description not sended to server + this.managedRepositories=ko.observableArray([]); + this.managedRepositories.subscribe(function(newValue){self.modified(true)}); + + this.modified=ko.observable(false); + } + + RepositoryGroupViewModel=function(repositoryGroup,update,repositoryGroupsViewModel){ + var self = this; + this.repositoryGroup=repositoryGroup; + this.update=update; + this.repositoryGroupsViewModel=repositoryGroupsViewModel; + this.availableRepositories=ko.observableArray([]); + this.applicationUrl=null; + + for (var i=0;i<repositoryGroupsViewModel.managedRepositories().length;i++){ + if ( $.inArray(repositoryGroupsViewModel.managedRepositories()[i].id(),this.repositoryGroup.repositories())<0){ + this.availableRepositories.push(repositoryGroupsViewModel.managedRepositories()[i]); + } + } + + repositoryMoved=function(arg){ + $.log("repositoryMoved:"+arg.sourceIndex+" to " + arg.targetIndex); + var repositories=[]; + for(var i=0;i<self.repositoryGroup.managedRepositories().length;i++){ + repositories.push(self.repositoryGroup.managedRepositories()[i].id()); + } + self.repositoryGroup.repositories(repositories); + self.repositoryGroup.modified(true); + var mainContent=$("#main-content"); + mainContent.find("#repository-groups-edit-available-repositories").find(".icon-plus-sign" ).off("click"); + mainContent.find("#repository-groups-edit-order-div").find(".icon-minus-sign" ).off("click"); + self.renderSortableAvailables(self.repositoryGroupsViewModel); + self.renderSortableChoosed(self.repositoryGroupsViewModel); + } + + this.saveRepositoryGroup=function(repositoryGroup){ + if (self.update){ + self.repositoryGroupsViewModel.saveRepositoryGroup(repositoryGroup); + } else { + self.repositoryGroupsViewModel.addRepositoryGroup(repositoryGroup); + } + } + + this.removeRepository=function(id){ + $.log("removeRepository:"+id); + } + + this.removeAvailable=function(idVal){ + for (var i=0;i<self.repositoryGroupsViewModel.managedRepositories().length;i++){ + if(self.repositoryGroupsViewModel.managedRepositories()[i].id()==idVal){ + self.availableRepositories.remove(repositoryGroupsViewModel.managedRepositories()[i]); + } + } + + for(var i= 0;i<self.repositoryGroupsViewModel.managedRepositories().length;i++){ + if(self.repositoryGroupsViewModel.managedRepositories()[i].id()==idVal){ + $.log("find repo to add"); + self.repositoryGroup.repositories.push(idVal); + self.repositoryGroup.managedRepositories.push(findManagedRepository(idVal,self.repositoryGroupsViewModel.managedRepositories())); + } + } + $("#main-content").find("#repository-groups-edit-order-div").find("#minus-"+idVal ).on("click",function(){ + var idVal = $(this).attr("id"); + idVal=idVal.substringAfterFirst("minus-"); + self.removeChoosed(idVal); + }); + } + + this.renderSortableAvailables=function(repositoryGroupsViewModel){ + $("#main-content").find("#repository-groups-edit-available-repositories").find(".icon-plus-sign" ).on("click",function(){ + var idVal = $(this).attr("id"); + idVal=idVal.substringAfterFirst("plus-"); + self.removeAvailable(idVal); + }); + } + + this.removeChoosed=function(idVal){ + for (var i=0;i<self.repositoryGroupsViewModel.managedRepositories().length;i++){ + if(self.repositoryGroupsViewModel.managedRepositories()[i].id()==idVal){ + self.availableRepositories.push(repositoryGroupsViewModel.managedRepositories()[i]); + } + } + + for(var i= 0;i<self.repositoryGroup.repositories().length;i++){ + if(self.repositoryGroup.repositories()[i]==idVal){ + self.repositoryGroup.repositories.remove(self.repositoryGroup.repositories()[i]); + self.repositoryGroup.managedRepositories.remove(findManagedRepository(idVal,self.repositoryGroupsViewModel.managedRepositories())); + } + } + $("#main-content").find("#repository-groups-edit-available-repositories").find("#plus-"+idVal ).on("click",function(){ + var idVal = $(this).attr("id"); + idVal=idVal.substringAfterFirst("plus-"); + self.removeAvailable(idVal); + }); + } + + this.renderSortableChoosed=function(repositoryGroupsViewModel){ + $("#main-content").find("#repository-groups-edit-order-div").find(".icon-minus-sign" ).on("click",function(){ + var idVal = $(this).attr("id"); + idVal=idVal.substringAfterFirst("minus-"); + self.removeChoosed(idVal); + }); + } + } + + RepositoryGroupsViewModel=function(){ + var self=this; + this.repositoryGroups=ko.observableArray([]); + this.managedRepositories=ko.observableArray([]); + this.applicationUrl=""; + + this.removeFromList=function(managedRepository){ + $.log("removeFromList"); + } + + this.findManagedRepository=function(id){ + return findManagedRepository(id,self.managedRepositories()); + } + this.deleteRepositoryGroup=function(repositoryGroup){ + openDialogConfirm( + function(){self.removeRepositoryGroup(repositoryGroup);window.modalConfirmDialog.modal('hide')}, + $.i18n.prop('ok'), $.i18n.prop('cancel'), + $.i18n.prop('repository.group.delete.confirm',repositoryGroup.id()), + $("#repository-group-delete-warning-tmpl").tmpl(self.repositoryGroup)); + } + this.removeRepositoryGroup=function(repositoryGroup){ + clearUserMessages(); + $.ajax("restServices/archivaServices/repositoryGroupService/deleteRepositoryGroup/"+encodeURIComponent(repositoryGroup.id()), + { + type: "GET", + success: function(data) { + var message=$.i18n.prop('repository.group.deleted',repositoryGroup.id()); + displaySuccessMessage(message); + self.repositoryGroups.remove(repositoryGroup); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + } + } + ); + } + + this.editRepositoryGroup=function(repositoryGroup){ + + var mainContent=$("#main-content"); + $.ajax({ + url: "restServices/archivaServices/archivaAdministrationService/applicationUrl", + type: "GET", + dataType: 'text', + success: function(applicationUrl){ + $.log("editRepositoryGroup:"+repositoryGroup.id()+",repositories:"+repositoryGroup.repositories().length+",managed:"+repositoryGroup.managedRepositories().length); + var repositoryGroupViewModel=new RepositoryGroupViewModel(repositoryGroup,true,self); + repositoryGroupViewModel.applicationUrl=applicationUrl; + activateRepositoryGroupEditTab(); + ko.applyBindings(repositoryGroupViewModel,mainContent.find("#repository-groups-edit" ).get(0)); + repositoryGroupViewModel.renderSortableChoosed(self); + repositoryGroupViewModel.renderSortableAvailables(self); + mainContent.find("#repository-groups-view-tabs-li-edit" ).find("a").html($.i18n.prop("edit")); + } + }); + } + + this.editRepositoryGroupWithId=function(repositoryGroupId){ + + $.each(self.repositoryGroups(), function(index, value) { + if(value.id()==repositoryGroupId){ + self.editRepositoryGroup(value); + } + }); + } + + this.saveRepositoryGroup=function(repositoryGroup){ + clearUserMessages(); + var userMessages=$("#user-messages"); + userMessages.html(mediumSpinnerImg()); + $("#repository-group-save" ).button('loading'); + $.ajax("restServices/archivaServices/repositoryGroupService/updateRepositoryGroup", + { + type: "POST", + contentType: 'application/json', + data:ko.toJSON(repositoryGroup), + dataType: 'json', + success: function(data) { + $.log("update repositoryGroup id:"+repositoryGroup.id()); + var message=$.i18n.prop('repository.group.updated',repositoryGroup.id()); + displaySuccessMessage(message); + repositoryGroup.modified(false); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + }, + complete:function(data){ + $("#repository-group-save" ).button('reset'); + removeMediumSpinnerImg(userMessages); + } + } + ); + + } + + this.addRepositoryGroup=function(repositoryGroup){ + clearUserMessages(); + $.ajax("restServices/archivaServices/repositoryGroupService/addRepositoryGroup", + { + type: "POST", + contentType: 'application/json', + data: ko.toJSON(repositoryGroup), + dataType: 'json', + success: function(data) { + $.log("update repositoryGroup id:"+repositoryGroup.id()); + var message=$.i18n.prop('repository.group.added',repositoryGroup.id()); + displaySuccessMessage(message); + repositoryGroup.modified(false); + self.repositoryGroups.push(repositoryGroup); + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + } + } + ); + + } + + getManagedRepository=function(id){ + $.log("getManagedRepository:"+id); + return findManagedRepository(self.managedRepositories()); + } + + } + + displayRepositoryGroups=function(successFn){ + screenChange(); + var mainContent = $("#main-content"); + mainContent.html(mediumSpinnerImg()); + this.repositoryGroupsViewModel=new RepositoryGroupsViewModel(); + var self=this; + + loadManagedRepositories(function(data) { + + $.ajax({ + url: "restServices/archivaServices/archivaAdministrationService/applicationUrl", + type: "GET", + dataType: 'text', + success: function(applicationUrl){ + + self.repositoryGroupsViewModel.managedRepositories(mapManagedRepositories(data,applicationUrl)); + self.repositoryGroupsViewModel.applicationUrl=applicationUrl; + $.ajax("restServices/archivaServices/repositoryGroupService/getRepositoriesGroups", { + type: "GET", + dataType: 'json', + success: function(data) { + var mappedRepositoryGroups=mapRepositoryGroups(data); + for(var i=0;i<mappedRepositoryGroups.length;i++){ + mappedRepositoryGroups[i] + .managedRepositories(self.mapManagedRepositoriesToRepositoryGroup(mappedRepositoryGroups[i])); + mappedRepositoryGroups[i].modified(false); + $.log("mappedRepositoryGroups.repositories().length:"+mappedRepositoryGroups[i].repositories().length); + } + mainContent.html($("#repositoryGroupsMain").tmpl()); + self.repositoryGroupsViewModel.repositoryGroups(mappedRepositoryGroups); + $.log("displayRepositoryGroups#applyBindings before"); + ko.applyBindings(self.repositoryGroupsViewModel,mainContent.find("#repository-groups-view" ).get(0)); + $.log("displayRepositoryGroups#applyBindings after"); + + mainContent.find("#repository-groups-view-tabs").on('show', function (e) { + if ($(e.target).attr("href")=="#repository-groups-edit") { + var repositoryGroup = new RepositoryGroup(); + var repositoryGroupViewModel=new RepositoryGroupViewModel(repositoryGroup,false,self.repositoryGroupsViewModel); + + activateRepositoryGroupEditTab(); + ko.applyBindings(repositoryGroupViewModel,mainContent.find("#repository-groups-edit" ).get(0)); + repositoryGroupViewModel.renderSortableChoosed(self.repositoryGroupsViewModel); + repositoryGroupViewModel.renderSortableAvailables(self.repositoryGroupsViewModel); + } + if ($(e.target).attr("href")=="#repository-groups-view") { + mainContent.find("#repository-groups-view-tabs-li-edit a").html($.i18n.prop("add")); + clearUserMessages(); + } + + }); + + if(successFn){ + successFn(self.repositoryGroupsViewModel); + } + + } + } + ); + + } + }); + }); + + this.mapManagedRepositoriesToRepositoryGroup=function(repositoryGroup){ + $.log("mapManagedRepositoriesToRepositoryGroup"); + var managedRepositories=new Array(); + if (!repositoryGroup.repositories()) { + repositoryGroup.repositories(new Array()); + return managedRepositories; + } + for(var i=0;i<repositoryGroup.repositories().length;i++){ + managedRepositories.push(self.repositoryGroupsViewModel.findManagedRepository(repositoryGroup.repositories()[i])); + } + $.log("end mapManagedRepositoriesToRepositoryGroup"); + return managedRepositories; + } + + } + + + + activateRepositoryGroupsGridTab=function(){ + var mainContent = $("#main-content"); + mainContent.find("#repository-groups-view-tabs-content div[class*='tab-pane']").removeClass("active"); + mainContent.find("#repository-groups-view-tabs li").removeClass("active"); + + mainContent.find("#repository-groups-view").addClass("active"); + mainContent.find("#repository-groups-view-tabs-li-grid").addClass("active"); + mainContent.find("#repository-groups-view-tabs-li-edit a").html($.i18n.prop("add")); + + } + + activateRepositoryGroupEditTab=function(){ + var mainContent = $("#main-content"); + + mainContent.find("#repository-groups-view-tabs-content div[class*='tab-pane']").removeClass("active"); + mainContent.find("#repository-groups-view-tabs li").removeClass("active"); + + mainContent.find("#repository-groups-edit").addClass("active"); + mainContent.find("#repository-groups-view-tabs-li-edit").addClass("active"); + } + + mapRepositoryGroups=function(data){ + if (data == null){ + return new Array(); + } + var mappedRepositoryGroups = $.map(data, function(item) { + return mapRepositoryGroup(item); + }); + return mappedRepositoryGroups; + } + + mapRepositoryGroup=function(data){ + return new RepositoryGroup(data.id, mapStringArray(data.repositories)); + } + +}); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/search.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/search.js new file mode 100644 index 000000000..5c7175241 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/search.js @@ -0,0 +1,2102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +define("archiva.search",["jquery","i18n","jquery.tmpl","select2","knockout","knockout.simpleGrid","jqueryFileTree","prettify"] +, function(jquery,i18n,jqueryTmpl,select2,ko,koSimpleGrid) { + + //----------------------------------------- + // browse part + //----------------------------------------- + + BrowseViewModel=function(browseResultEntries,parentBrowseViewModel,groupId,repositoryId,feedsUrl){ + var self=this; + this.browseResultEntries=browseResultEntries; + this.parentBrowseViewModel=parentBrowseViewModel; + this.groupId=groupId; + this.repositoryId=repositoryId; + this.feedsUrl=feedsUrl; + displayGroupId=function(groupId){ + $.log("BrowseViewModel#displayGroupId,self.repositoryId:"+self.repositoryId); + if(self.repositoryId){ + window.sammyArchivaApplication.setLocation("#browse~"+self.repositoryId+"/"+groupId); + } else { + window.sammyArchivaApplication.setLocation("#browse/"+groupId); + } + } + displayParentGroupId=function(){ + $.log("called displayParentGroupId groupId:"+self.parentBrowseViewModel.groupId); + // if null parent is root level + if (self.parentBrowseViewModel.groupId){ + displayGroupDetail(self.parentBrowseViewModel.groupId,self.parentBrowseViewModel); + } else { + browseRoot(); + } + } + + breadCrumbEntries=function(){ + // root level ? + if (!self.parentBrowseViewModel){ + return []; + } + return calculateBreadCrumbEntries(self.groupId); + } + + displayProjectEntry=function(id){ + + // value org.apache.maven/maven-archiver + // artifactId can contains . + // value org.apache.aries/org.apache.aries.util + // split this org.apache.maven and maven-archiver + var artifactId = id.substring((self.groupId+'.').length,id.length);//.split("."); + var selectedRepo=getSelectedBrowsingRepository(); + + var location ="#artifact"; + if (selectedRepo){ + location+="~"+selectedRepo; + } + location+="/"+self.groupId+"/"+artifactId; + + window.sammyArchivaApplication.setLocation(location); + + } + + displayEntry=function(value){ + if (self.groupId){ + return value.substr(self.groupId.length+1,value.length-self.groupId.length); + } + return value; + } + + deleteKarma=function(){ + return hasKarma('archiva-delete-artifact'); + } + + deleteProject=function(groupId,projectId){ + $.log("deleteProject:"+groupId+"/"+projectId); + + var repoId=getSelectedBrowsingRepository(); + if(!repoId){ + var escapedGroupId=escapeDot(groupId ); + var selected = $("#main-content" ).find("#delete-"+escapedGroupId ); + selected.attr("data-content",$.i18n.prop('projectId.delete.missing.repoId')) + selected.popover({ + html:true, + template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><div class="popover-content"><p></p></div></div></div>', + placement:'top', + trigger:'manual'}); + selected.popover('show'); + selected.mouseover(function(){ + selected.popover("destroy"); + }); + return; + } + + + var previousHash=getUrlHash(); + $.log("previousHash:"+previousHash); + openDialogConfirm(function(){ + $("#dialog-confirm-modal-ok").button('loading'); + $.ajax({ + url:"restServices/archivaServices/repositoriesService/project/"+repoId+"/"+groupId+"/"+projectId, + type:"DELETE", + dataType:"json", + success:function(data){ + window.sammyArchivaApplication.setLocation(previousHash); + refreshContent(); + displaySuccessMessage( $.i18n.prop("projectId.deleted", groupId,projectId)); + }, + error:function(data){ + displayRestError(data,"user-messages"); + }, + complete:function(){ + $("#dialog-confirm-modal-ok").button('reset'); + closeDialogConfirm(); + } + }); + }, $.i18n.prop('ok'), + $.i18n.prop('cancel'), + $.i18n.prop('projectId.delete.confirm.title'), + $.i18n.prop('projectId.delete.confirm.save',groupId,projectId)); + } + } + + deleteGroupId=function(groupId){ + + var repoId=getSelectedBrowsingRepository(); + if(!repoId){ + var escapedGroupId=escapeDot(groupId ); + var selected = $("#main-content" ).find("#delete-"+escapedGroupId ); + selected.attr("data-content",$.i18n.prop('groupId.delete.missing.repoId')) + selected.popover({ + html:true, + template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><div class="popover-content"><p></p></div></div></div>', + placement:'top', + trigger:'manual'}); + selected.popover('show'); + selected.mouseover(function(){ + selected.popover("destroy"); + }); + return; + } + var previousHash=getUrlHash(); + $.log("previousHash:"+previousHash); + openDialogConfirm(function(){ + $("#dialog-confirm-modal-ok").button('loading'); + $.ajax({ + url:"restServices/archivaServices/repositoriesService/deleteGroupId?groupId="+groupId+"&repositoryId="+repoId, + type:"GET", + dataType:"json", + success:function(data){ + window.sammyArchivaApplication.setLocation(previousHash); + refreshContent(); + displaySuccessMessage( $.i18n.prop("groupdId.deleted", groupId)); + }, + error:function(data){ + displayRestError(data,"user-messages"); + }, + complete:function(){ + $("#dialog-confirm-modal-ok").button('reset'); + closeDialogConfirm(); + } + }); + }, $.i18n.prop('ok'), + $.i18n.prop('cancel'), + $.i18n.prop('groupId.delete.confirm.title'), + $.i18n.prop('groupId.delete.confirm.save',groupId)); + + } + + calculateBreadCrumbEntries=function(groupId){ + if (!groupId){ + return []; + } + var splitted = groupId.split("."); + var breadCrumbEntries=[]; + var curGroupId=""; + for (var i=0;i<splitted.length;i++){ + curGroupId+=splitted[i]; + breadCrumbEntries.push(new BreadCrumbEntry(curGroupId,splitted[i])); + curGroupId+="." + } + return breadCrumbEntries; + } + + displayGroupDetail=function(groupId,parentBrowseViewModel,restUrl,repositoryId,feedsUrl){ + var mainContent = $("#main-content"); + mainContent.find("#browse_artifact_detail").hide(); + var browseResult=mainContent.find("#browse_result"); + browseResult.show(); + mainContent.find("#browse_artifact" ).hide(); + var browseBreadCrumb=mainContent.find("#browse_breadcrumb"); + mainContent.find("#main_browse_result_content").hide( "slide", {}, 300, + function(){ + browseResult.html(mediumSpinnerImg()); + browseBreadCrumb.html(smallSpinnerImg()); + mainContent.find("#main_browse_result_content").show(); + var url = ""; + if (!restUrl) { + url="restServices/archivaServices/browseService/browseGroupId/"+encodeURIComponent(groupId); + var selectedRepo=getSelectedBrowsingRepository(); + if (selectedRepo){ + url+="?repositoryId="+selectedRepo; + } + } else { + url=restUrl; + } + + $.ajax(url, { + type: "GET", + dataType: 'json', + success: function(data) { + var browseResultEntries = mapBrowseResultEntries(data); + var browseViewModel = new BrowseViewModel(browseResultEntries,parentBrowseViewModel,groupId,repositoryId,feedsUrl); + ko.applyBindings(browseViewModel,browseBreadCrumb.get(0)); + ko.applyBindings(browseViewModel,browseResult.get(0)); + enableAutocompleBrowse(groupId); + } + }); + } + ); + } + + ArtifactDetailViewModel=function(groupId,artifactId){ + var self=this; + this.versions=ko.observableArray([]); + this.projectVersionMetadata=null; + this.groupId=groupId; + this.artifactId=artifactId; + breadCrumbEntries=function(){ + var entries = calculateBreadCrumbEntries(self.groupId); + entries.push(new BreadCrumbEntry("foo",self.artifactId)); + return entries; + } + displayArtifactInfo=function(){ + if ($("#main-content").find("#artifact-info:visible" ).length>0) { + $("#main-content").find("#artifact-info" ).hide(); + } else { + $("#main-content").find("#artifact-info" ).show(); + } + } + + deleteVersion=function(version){ + var repoId=getSelectedBrowsingRepository(); + if(!repoId){ + var escapedVersion=escapeDot(version); + var selected = $("#main-content" ).find("#delete-"+escapedVersion ); + selected.attr("data-content",$.i18n.prop('version.delete.missing.repoId')) + selected.popover({ + html:true, + template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><div class="popover-content"><p></p></div></div></div>', + placement:'top', + trigger:'manual'}); + selected.popover('show'); + selected.mouseover(function(){ + selected.popover("destroy"); + }); + return; + } + + clearUserMessages(); + var artifact = new Artifact(repoId,null,self.groupId,self.artifactId,repoId,version); + openDialogConfirm(function(){ + var url = "restServices/archivaServices/repositoriesService/projectVersion/"+repoId; + url+="/"+encodeURIComponent(self.groupId)+"/"+encodeURIComponent(self.artifactId); + url+="/"+encodeURIComponent(version); + $("#dialog-confirm-modal-ok").button('loading'); + $.ajax({ + url:url, + type:"DELETE", + success:function(data){ + self.versions.remove(version); + refreshContent(); + displaySuccessMessage( $.i18n.prop('artifact.deleted')); + }, + error:function(data){ + displayRestError( data,"user-messages"); + }, + complete:function(){ + $("#dialog-confirm-modal-ok").button('reset'); + closeDialogConfirm(); + } + }); + }, $.i18n.prop('ok'), + $.i18n.prop('cancel'), + $.i18n.prop('artifact.delete.confirm.title'), + $.i18n.prop('artifact.delete.confirm.save')); + } + + displayArtifactVersionDetail=function(version){ + var selectedRepo=getSelectedBrowsingRepository(); + var location ="#artifact"; + if (selectedRepo){ + location+="~"+selectedRepo; + } + location+="/"+self.groupId+"/"+self.artifactId+"/"+version; + window.sammyArchivaApplication.setLocation(location); + } + + displayGroupId=function(groupId){ + var selectedRepo=getSelectedBrowsingRepository(); + var location ="#browse"; + if (selectedRepo){ + location+="~"+selectedRepo; + } + location+="/"+groupId; + window.sammyArchivaApplication.setLocation(location); + } + + } + + displayArtifactVersionDetailViewModel=function(groupId,artifactId,version){ + $.log("displayArtifactVersionDetailViewModel:"+groupId+":"+artifactId+":"+version); + var artifactVersionDetailViewModel = new ArtifactVersionDetailViewModel (groupId,artifactId,version) + artifactVersionDetailViewModel.display(); + } + + + ArtifactVersionDetailViewModel=function(groupId,artifactId,version,repositoryId){ + var mainContent = $("#main-content"); + var self=this; + this.groupId=groupId; + this.artifactId=artifactId; + this.version=version; + this.projectVersionMetadata=null; + this.entries=ko.observableArray([]); + this.repositoryId=repositoryId; + + displayGroupId=function(groupId){ + var location ="#browse"; + if (self.repositoryId){ + location+="~"+self.repositoryId; + } + location+="/"+groupId; + window.sammyArchivaApplication.setLocation(location); + } + + displayParent=function(){ + var selectedRepo=getSelectedBrowsingRepository(); + var location ="#artifact"; + if (selectedRepo){ + location+="~"+selectedRepo; + } + location+="/"+self.projectVersionMetadata.mavenFacet.parent.groupId+"/"+self.projectVersionMetadata.mavenFacet.parent.artifactId; + location+="/"+self.projectVersionMetadata.mavenFacet.parent.version; + + window.sammyArchivaApplication.setLocation(location); + + } + + breadCrumbEntries=function(){ + var entries = calculateBreadCrumbEntries(self.groupId); + var artifactBreadCrumbEntry = new BreadCrumbEntry(self.groupId,self.artifactId); + artifactBreadCrumbEntry.artifactId=self.artifactId; + artifactBreadCrumbEntry.artifact=true; + entries.push(artifactBreadCrumbEntry); + entries.push(new BreadCrumbEntry("foo",self.version)); + return entries; + } + + this.display=function(afterCallbackFn){ + mainContent.find("#browse_breadcrumb").hide("slide", {}, 300,function(){ + mainContent.find("#browse_artifact").hide("slide", {}, 300,function(){ + + mainContent.find("#browse_artifact_detail").show(); + mainContent.find("#browse_artifact_detail").html(mediumSpinnerImg()); + mainContent.find("#browse_breadcrumb" ).show(); + mainContent.find("#browse_breadcrumb" ).html(mediumSpinnerImg()); + var metadataUrl="restServices/archivaServices/browseService/projectVersionMetadata/"+encodeURIComponent(groupId)+"/"+encodeURIComponent(artifactId); + metadataUrl+="/"+encodeURIComponent(version); + var selectedRepo=getSelectedBrowsingRepository(); + if (selectedRepo){ + metadataUrl+="?repositoryId="+encodeURIComponent(selectedRepo); + } + + $.ajax(metadataUrl, { + type: "GET", + dataType: 'json', + success: function(data) { + self.projectVersionMetadata=mapProjectVersionMetadata(data); + + //pagination for dependencies + self.projectVersionMetadata.dependencies=ko.observableArray(self.projectVersionMetadata.dependencies?self.projectVersionMetadata.dependencies:[]); + self.gridViewModel = new ko.simpleGrid.viewModel({ + data: self.projectVersionMetadata.dependencies(), + columns: [], + pageSize: 7, + gridUpdateCallBack: function(){ + // nope + } + }); + + ko.applyBindings(self,mainContent.find("#browse_artifact_detail" ).get(0)); + ko.applyBindings(self,mainContent.find("#browse_breadcrumb" ).get(0)); + mainContent.find("#browse-autocomplete" ).hide(); + mainContent.find("#browse-autocomplete-divider" ).hide(); + + //calculate tree content + var treeContentDiv=mainContent.find("#artifact-details-dependency-tree-content" ); + if( $.trim(treeContentDiv.html()).length<1){ + treeContentDiv.html(mediumSpinnerImg()); + var treeDependencyUrl="restServices/archivaServices/browseService/treeEntries/"+encodeURIComponent(groupId); + treeDependencyUrl+="/"+encodeURIComponent(artifactId); + treeDependencyUrl+="/"+encodeURIComponent(version); + var selectedRepo=getSelectedBrowsingRepository(); + if (selectedRepo){ + treeDependencyUrl+="?repositoryId="+encodeURIComponent(selectedRepo); + } + $.ajax(treeDependencyUrl, { + type: "GET", + dataType: 'json', + success: function(data) { + var treeEntries = mapTreeEntries(data); + treeContentDiv.html($("#dependency_tree_tmpl" ).tmpl({treeEntries: treeEntries})); + } + }); + } + + + mainContent.find("#artifact-details-tabs").on('show', function (e) { + $.log("e.target:"+e.target); + if ($(e.target).attr("data-target")=="#artifact-details-info-content") { + var location ="#artifact"; + if (self.repositoryId){ + location+="~"+self.repositoryId; + } + location+="/"+self.groupId+"/"+self.artifactId+"/"+self.version; + + window.sammyArchivaApplication.setLocation(location); + return; + } + + + if ($(e.target).attr("data-target")=="#artifact-details-dependencies-content") { + var location ="#artifact-dependencies"; + if (self.repositoryId){ + location+="~"+self.repositoryId; + } + location+="/"+self.groupId+"/"+self.artifactId+"/"+self.version; + + window.sammyArchivaApplication.setLocation(location); + return; + } + + if ($(e.target).attr("data-target")=="#artifact-details-dependency-tree-content") { + var location ="#artifact-dependency-tree"; + if (self.repositoryId){ + location+="~"+self.repositoryId; + } + location+="/"+self.groupId+"/"+self.artifactId+"/"+self.version; + + window.sammyArchivaApplication.setLocation(location); + return; + } + + if ($(e.target).attr("data-target")=="#artifact-details-used-by-content") { + var location ="#artifact-used-by"; + if (self.repositoryId){ + location+="~"+self.repositoryId; + } + location+="/"+self.groupId+"/"+self.artifactId+"/"+self.version; + + window.sammyArchivaApplication.setLocation(location); + return; + } + + if ($(e.target).attr("href")=="#artifact-details-metadatas-content") { + var location ="#artifact-metadatas"; + if (self.repositoryId){ + location+="~"+self.repositoryId; + } + location+="/"+self.groupId+"/"+self.artifactId+"/"+self.version; + + window.sammyArchivaApplication.setLocation(location); + return; + } + + if ($(e.target).attr("href")=="#artifact-details-download-content") { + var location ="#artifact-details-download-content"; + if (self.repositoryId){ + location+="~"+self.repositoryId; + } + location+="/"+self.groupId+"/"+self.artifactId+"/"+self.version; + + window.sammyArchivaApplication.setLocation(location); + return; + } + if ($(e.target).attr("href")=="#artifact-details-files-content") { + var location ="#artifact-details-files-content"; + if (self.repositoryId){ + location+="~"+self.repositoryId; + } + location+="/"+self.groupId+"/"+self.artifactId+"/"+self.version; + + window.sammyArchivaApplication.setLocation(location); + return; + } + if ($(e.target).attr("href")=="#artifact-details-mailing-list-content") { + var location ="#artifact-mailing-list"; + if (self.repositoryId){ + location+="~"+self.repositoryId; + } + location+="/"+self.groupId+"/"+self.artifactId+"/"+self.version; + + window.sammyArchivaApplication.setLocation(location); + return; + } + }); + if(afterCallbackFn){ + afterCallbackFn(self); + } + } + + }); + + }); + }); + } + + + + displayGroup=function(groupId){ + var selectedRepo=getSelectedBrowsingRepository(); + var location ="#browse"; + if (selectedRepo){ + location+="~"+selectedRepo; + } + location+="/"+groupId; + + window.sammyArchivaApplication.setLocation(location); + } + + displayArtifactDetailView=function(groupId, artifactId){ + var selectedRepo=getSelectedBrowsingRepository(); + var location ="#artifact"; + if (selectedRepo){ + location+="~"+selectedRepo; + } + location+="/"+groupId+"/"+artifactId; + + window.sammyArchivaApplication.setLocation(location); + + } + + displayArtifactVersionDetailViewModel=function(groupId,artifactId,version){ + $.log("ArtifactVersionDetailViewModel#displayArtifactVersionDetailViewModel:"+groupId+":"+artifactId+":"+version); + var selectedRepo=getSelectedBrowsingRepository(); + var location ="#artifact"; + if (selectedRepo){ + location+="~"+selectedRepo; + } + location+="/"+groupId+"/"+artifactId+"/"+version; + + self.groupId=groupId; + self.artifactId=artifactId; + self.version=version; + $("#main-content" ).find("#browse_artifact_detail" ).empty(); + + window.sammyArchivaApplication.setLocation(location); + } + + + addProperty=function(){ + self.entries.push(new MetadataEntry("","",true)); + } + + deleteProperty=function(entry){ + var metadatasUrl="restServices/archivaServices/browseService/metadata/"+encodeURIComponent(groupId); + metadatasUrl+="/"+encodeURIComponent(artifactId); + metadatasUrl+="/"+encodeURIComponent(version); + metadatasUrl+="/"+encodeURIComponent(entry.key()); + var selectedRepo=getSelectedBrowsingRepository(); + + if(!selectedRepo){ + clearUserMessages(); + displayErrorMessage($.i18n.prop('repository.selected.missing')); + return; + } + + metadatasUrl+="?repositoryId="+encodeURIComponent(selectedRepo); + + $.ajax(metadatasUrl, { + type: "DELETE", + dataType: 'json', + success: function(data) { + clearUserMessages(); + displaySuccessMessage( $.i18n.prop("artifact.metadata.deleted")); + self.entries.remove(entry); + } + }); + + } + + hasSavePropertyKarma=function(){ + return hasKarma("archiva-add-metadata"); + } + + hasDeletePropertyKarma=function(){ + return hasKarma("archiva-delete-metadata"); + } + + saveProperty=function(entry){ + if($.trim(entry.key() ).length<1){ + clearUserMessages(); + displayErrorMessage( $.i18n.prop("artifact.metadata.key.mandatory")); + return; + } + if($.trim(entry.value() ).length<1){ + clearUserMessages(); + displayErrorMessage( $.i18n.prop("artifact.metadata.value.mandatory")); + return; + } + + var selectedRepo=getSelectedBrowsingRepository(); + + if(!selectedRepo){ + clearUserMessages(); + displayErrorMessage($.i18n.prop('repository.selected.missing')); + return; + } + + var metadatasUrl="restServices/archivaServices/browseService/metadata/"+encodeURIComponent(groupId); + metadatasUrl+="/"+encodeURIComponent(artifactId); + metadatasUrl+="/"+encodeURIComponent(version); + metadatasUrl+="/"+encodeURIComponent(entry.key()); + metadatasUrl+="/"+encodeURIComponent(entry.value()); + + if (selectedRepo){ + metadatasUrl+="?repositoryId="+encodeURIComponent(selectedRepo); + } + $.ajax(metadatasUrl, { + type: "PUT", + dataType: 'json', + success: function(data) { + clearUserMessages(); + displaySuccessMessage( $.i18n.prop("artifact.metadata.added")); + entry.editable(false); + entry.modified(false); + } + }); + } + + + this.gridMetatadasViewModel = new ko.simpleGrid.viewModel({ + data: self.entries, + pageSize: 10 + }); + + } + + ArtifactDetailsDownloadViewModel=function(artifacts, artifactVersionDetailViewModel){ + this.artifacts=ko.observableArray(artifacts); + this.artifactVersionDetailViewModel=artifactVersionDetailViewModel; + var self=this; + deleteArtifact=function(artifact){ + + clearUserMessages(); + + openDialogConfirm(function(){ + $("#dialog-confirm-modal-ok").button('loading'); + $.ajax({ + url:"restServices/archivaServices/repositoriesService/deleteArtifact", + type:"POST", + dataType:"json", + contentType: 'application/json', + data: ko.toJSON(artifact), + success:function(data){ + self.artifacts.remove(artifact); + displaySuccessMessage( $.i18n.prop('artifact.deleted')); + $("#main-content").find("#artifact-details-download-content" ).html(smallSpinnerImg()); + // reload datas from server + var artifactDownloadInfosUrl = "restServices/archivaServices/browseService/artifactDownloadInfos/"+encodeURIComponent(self.artifactVersionDetailViewModel.groupId); + artifactDownloadInfosUrl+="/"+encodeURIComponent(self.artifactVersionDetailViewModel.artifactId)+"/"+encodeURIComponent(self.artifactVersionDetailViewModel.version); + artifactDownloadInfosUrl+="?repositoryId="+encodeURIComponent(getSelectedBrowsingRepository()); + + $.get(artifactDownloadInfosUrl,function(data){ + self.artifacts(mapArtifacts(data)); + }); + + }, + error:function(data){ + displayRestError(data,"user-messages"); + }, + complete:function(){ + $("#dialog-confirm-modal-ok").button('reset'); + closeDialogConfirm(); + } + }); + }, $.i18n.prop('ok'), + $.i18n.prop('cancel'), + $.i18n.prop('artifact.delete.confirm.title'), + $.i18n.prop('artifact.delete.confirm.save')); + + } + + this.deleteKarma = hasKarma('archiva-delete-artifact'); + + } + + displayArtifactDownloadContent=function(artifactVersionDetailViewModel){ + var mainContent=$("#main-content"); + mainContent.find("#artifact-details-download-content" ).html(smallSpinnerImg()); + var artifactDownloadInfosUrl = "restServices/archivaServices/browseService/artifactDownloadInfos/"+encodeURIComponent(artifactVersionDetailViewModel.groupId); + artifactDownloadInfosUrl+="/"+encodeURIComponent(artifactVersionDetailViewModel.artifactId)+"/"+encodeURIComponent(artifactVersionDetailViewModel.version); + artifactDownloadInfosUrl+="?repositoryId="+encodeURIComponent(getSelectedBrowsingRepository()); + $.get(artifactDownloadInfosUrl,function(data){ + var artifactDetailsDownloadViewModel = new ArtifactDetailsDownloadViewModel(mapArtifacts(data),artifactVersionDetailViewModel); + mainContent.find("#artifact-details-download-content" ).attr("data-bind",'template:{name:"artifact-details-download-content_tmpl"}'); + ko.applyBindings(artifactDetailsDownloadViewModel,mainContent.find("#artifact-details-download-content" ).get(0)); + + + mainContent.find("#artifact-download-list-files li img" ).on("click",function(){ + mainContent.find("#artifact_content_tree").empty(); + var contentText = mainContent.find("#artifact-content-text" ); + contentText.empty(); + var idValue = $(this ).attr("id"); + var splitted = idValue.split(":"); + + var classifier=splitted[0]; + var version=splitted[1]; + var type = splitted[2]; + + $.log("click:" + idValue + " -> " + classifier + ":" + type + ":" + version); + if (type=="pom"){ + $.log("show pom"); + var pomContentUrl = "restServices/archivaServices/browseService/artifactContentText/"+encodeURIComponent(artifactVersionDetailViewModel.groupId); + pomContentUrl+="/"+encodeURIComponent(artifactVersionDetailViewModel.artifactId)+"/"+encodeURIComponent(version); + pomContentUrl+="?repositoryId="+encodeURIComponent(getSelectedBrowsingRepository()); + pomContentUrl+="&t=pom"; + contentText.html(mediumSpinnerImg()); + $.ajax({ + url: pomContentUrl, + success: function(data) { + var text = data.content.replace(/</g,'<'); + text=text.replace(/>/g,">"); + contentText.html(text); + prettyPrint(); + // olamy do not move to anchor to not loose nav history + //goToAnchor("artifact-content-text-header"); + //window.location.href=window.location+"#artifact-content-text-header"; + } + }); + return; + } + var entriesUrl = "restServices/archivaServices/browseService/artifactContentEntries/"+encodeURIComponent(artifactVersionDetailViewModel.groupId); + entriesUrl+="/"+encodeURIComponent(artifactVersionDetailViewModel.artifactId)+"/"+encodeURIComponent(version); + entriesUrl+="?repositoryId="+encodeURIComponent(getSelectedBrowsingRepository()); + if(classifier){ + entriesUrl+="&c="+encodeURIComponent(classifier); + } + $("#main-content").find("#artifact_content_tree").fileTree({ + script: entriesUrl, + root: "" + },function(file) { + $.log("file:"+file.substringBeforeLast("/")+',classifier:'+classifier); + var fileContentUrl = "restServices/archivaServices/browseService/artifactContentText/"+encodeURIComponent(artifactVersionDetailViewModel.groupId); + fileContentUrl+="/"+encodeURIComponent(artifactVersionDetailViewModel.artifactId)+"/"+encodeURIComponent(version); + fileContentUrl+="?repositoryId="+encodeURIComponent(getSelectedBrowsingRepository()); + if(type){ + fileContentUrl+="&t="+encodeURIComponent(type); + } + if(classifier){ + fileContentUrl+="&c="+encodeURIComponent(classifier); + } + fileContentUrl+="&p="+encodeURIComponent(file.substringBeforeLast("/")); + $.ajax({ + url: fileContentUrl, + success: function(data) { + var text = data.content.replace(/</g,'<'); + text=text.replace(/>/g,">"); + mainContent.find("#artifact-content-text" ).html(smallSpinnerImg()); + mainContent.find("#artifact-content-text" ).html(text); + prettyPrint(); + // olamy do not move to anchor to not loose nav history + //goToAnchor("artifact-content-text-header"); + //window.location.href=window.location+"#artifact-content-text-header"; + } + }); + } + ); + }); + + + }); + return; + } + + displayArtifactFilesContent=function(artifactVersionDetailViewModel){ + var mainContent = $("#main-content"); + mainContent.find("#artifact-details-files-content" ).html(smallSpinnerImg()); + var artifactDownloadInfosUrl = "restServices/archivaServices/browseService/artifactDownloadInfos/"+encodeURIComponent(artifactVersionDetailViewModel.groupId); + artifactDownloadInfosUrl+="/"+encodeURIComponent(artifactVersionDetailViewModel.artifactId)+"/"+encodeURIComponent(artifactVersionDetailViewModel.version); + artifactDownloadInfosUrl+="?repositoryId="+encodeURIComponent(getSelectedBrowsingRepository()); + + $.get(artifactDownloadInfosUrl,function(data){ + $("#artifact-details-files-content" ).html($("#artifact-details-files-content_tmpl").tmpl({artifactDownloadInfos:data})); + mainContent.find("#artifact-content-list-files li" ).on("click",function(){ + mainContent.find("#artifact_content_tree").empty(); + var contentText = mainContent.find("#artifact-content-text" ); + contentText.empty(); + var idValue = $(this ).attr("id"); + var splitted = idValue.split(":"); + + var classifier=splitted[0]; + var version=splitted[1]; + var type = splitted[2]; + + $.log("click:" + idValue + " -> " + classifier + ":" + type + ":" + version); + if (type=="pom"){ + $.log("show pom"); + var pomContentUrl = "restServices/archivaServices/browseService/artifactContentText/"+encodeURIComponent(artifactVersionDetailViewModel.groupId); + pomContentUrl+="/"+encodeURIComponent(artifactVersionDetailViewModel.artifactId)+"/"+encodeURIComponent(version); + pomContentUrl+="?repositoryId="+encodeURIComponent(getSelectedBrowsingRepository()); + pomContentUrl+="&t=pom"; + contentText.html(mediumSpinnerImg()); + $.ajax({ + url: pomContentUrl, + success: function(data) { + var text = data.content.replace(/</g,'<'); + text=text.replace(/>/g,">"); + contentText.html(text); + prettyPrint(); + // olamy do not move to anchor to not loose nav history + //goToAnchor("artifact-content-text-header"); + //window.location.href=window.location+"#artifact-content-text-header"; + } + }); + return; + } + var entriesUrl = "restServices/archivaServices/browseService/artifactContentEntries/"+encodeURIComponent(artifactVersionDetailViewModel.groupId); + entriesUrl+="/"+encodeURIComponent(artifactVersionDetailViewModel.artifactId)+"/"+encodeURIComponent(version); + entriesUrl+="?repositoryId="+encodeURIComponent(getSelectedBrowsingRepository()); + if(classifier){ + entriesUrl+="&c="+encodeURIComponent(classifier); + } + $("#main-content").find("#artifact_content_tree").fileTree({ + script: entriesUrl, + root: "" + },function(file) { + $.log("file:"+file.substringBeforeLast("/")+',classifier:'+classifier); + var fileContentUrl = "restServices/archivaServices/browseService/artifactContentText/"+encodeURIComponent(artifactVersionDetailViewModel.groupId); + fileContentUrl+="/"+encodeURIComponent(artifactVersionDetailViewModel.artifactId)+"/"+encodeURIComponent(version); + fileContentUrl+="?repositoryId="+encodeURIComponent(getSelectedBrowsingRepository()); + if(type){ + fileContentUrl+="&t="+encodeURIComponent(type); + } + if(classifier){ + fileContentUrl+="&c="+encodeURIComponent(classifier); + } + fileContentUrl+="&p="+encodeURIComponent(file.substringBeforeLast("/")); + $.ajax({ + url: fileContentUrl, + success: function(data) { + var text = data.content.replace(/</g,'<'); + text=text.replace(/>/g,">"); + mainContent.find("#artifact-content-text" ).html(smallSpinnerImg()); + mainContent.find("#artifact-content-text" ).html(text); + prettyPrint(); + // olamy do not move to anchor to not loose nav history + //goToAnchor("artifact-content-text-header"); + //window.location.href=window.location+"#artifact-content-text-header"; + } + }); + } + ); + }); + + }); + + } + + ArtifactContentEntry=function(path,file,depth){ + this.path=path; + this.file=file; + this.depth=depth; + } + + mapArtifactContentEntries=function(data){ + if(data==null){ + return []; + } + if ( $.isArray(data)){ + return $.map(data,function(e){ + return new ArtifactContentEntry(e.path,e.file,e.depth); + }) + } + return new ArtifactContentEntry(data.path,data.file,data.depth); + } + + MetadataEntry=function(key,value,editable){ + var self=this; + this.key=ko.observable(key); + this.key.subscribe(function(newValue){self.modified(true)}); + this.value=ko.observable(value); + this.value.subscribe(function(newValue){self.modified(true)}); + this.editable=ko.observable(editable); + this.modified=ko.observable(false) + } + + TreeEntry=function(artifact,childs){ + this.artifact=artifact; + this.childs=childs; + } + + mapTreeEntries=function(data){ + if (data==null){ + return []; + } + return $.map(data,function(e) { + return new TreeEntry(mapArtifact(e.artifact),mapTreeEntries(e.childs)); + }) + } + + /** + * display groupId note #main-content must contains browse-tmpl + * @param groupId + */ + generalDisplayGroup=function(groupId) { + $.log("generalDisplayGroup"); + var selectedRepo=getSelectedBrowsingRepository(); + var location ="#browse"; + if (selectedRepo){ + location+="~"+selectedRepo; + } + location+="/"+groupId; + + window.sammyArchivaApplication.setLocation(location); + } + + /** + * display groupId/artifactId detail note #main-content must contains browse-tmpl + * @param groupId + * @param artifactId + */ + generalDisplayArtifactDetailView=function(groupId, artifactId){ + var selectedRepo=getSelectedBrowsingRepository(); + var location ="#artifact"; + if (selectedRepo){ + location+="~"+selectedRepo; + } + location+="/"+groupId+"/"+artifactId; + + window.sammyArchivaApplication.setLocation(location); + } + + /** + * display groupId/artifactId/version detail note #main-content must contains browse-tmpl + * @param groupId + * @param artifactId + * @param version + */ + generalDisplayArtifactVersionDetailViewModel=function(groupId,artifactId,version){ + var selectedRepo=getSelectedBrowsingRepository(); + var location ="#artifact"; + if (selectedRepo){ + location+="~"+selectedRepo; + } + location+="/"+groupId+"/"+artifactId+"/"+version; + + window.sammyArchivaApplication.setLocation(location); + } + + goToBrowseArtifactDetail=function(groupId, artifactId,repositoryId){ + $.log("goToBrowseArtifactDetail:"+groupId+":"+artifactId); + //displayBrowseGroupId(groupId,null,null); + displayArtifactDetail(groupId,artifactId,null,null,repositoryId); + } + + /** + * + */ + displayBrowseGroupId=function(groupId,repositoryId,artifactId){ + clearUserMessages(); + $.log("displayBrowseGroupId:"+groupId+":"+repositoryId); + userRepositoriesCall( + function(data){ + + $.ajax({ + url: "restServices/archivaServices/archivaAdministrationService/applicationUrl", + type: "GET", + dataType: 'text', + success: function(applicationUrl){ + + var mainContent = $("#main-content"); + mainContent.html($("#browse-tmpl" ).tmpl()); + mainContent.find("#browse_result").html(mediumSpinnerImg()); + var parentBrowseViewModel=new BrowseViewModel(null,null,null,repositoryId); + var url="restServices/archivaServices/browseService/browseGroupId/"+encodeURIComponent(groupId); + var feedsUrl=applicationUrl?applicationUrl:window.location.toString().substringBeforeLast("/").substringBeforeLast("/"); + if (repositoryId){ + url+="?repositoryId="+repositoryId; + // we are browsing a groupId so 2 substringBeforeLast + + feedsUrl+="/feeds/"+repositoryId; + mainContent.find("#selected_repository" ).html($("#selected_repository_tmpl" ) + .tmpl({repositories:data,selected:repositoryId,feedsUrl:feedsUrl})); + }else{ + feedsUrl+="/feeds"; + mainContent.find("#selected_repository" ).html($("#selected_repository_tmpl" ) + .tmpl({repositories:data,selected:"",feedsUrl:null})); + } + displayGroupDetail(groupId,parentBrowseViewModel,url,repositoryId,feedsUrl); + + } + }); + + } + ); + + } + + goToArtifactDetail=function(groupId,artifactId){ + var selectedRepo=getSelectedBrowsingRepository(); + var location ="#artifact"; + if (selectedRepo){ + location+="~"+selectedRepo; + } + location+="/"+groupId+"/"+artifactId; + + window.sammyArchivaApplication.setLocation(location); + } + + /** + * + * @param groupId + * @param artifactId + * @param parentBrowseViewModel + * @param restUrl + * @param repositoryId + */ + displayArtifactDetail=function(groupId,artifactId,parentBrowseViewModel,restUrl,repositoryId){ + $.log("displayArtifactDetail:"+groupId+":"+artifactId); + var artifactDetailViewModel=new ArtifactDetailViewModel(groupId,artifactId); + var mainContent = $("#main-content"); + + mainContent.html($("#browse-tmpl" ).tmpl()); + + userRepositoriesCall( + function(data){ + + + $.ajax({ + url: "restServices/archivaServices/archivaAdministrationService/applicationUrl", + type: "GET", + dataType: 'text', + success: function(applicationUrl){ + + var feedsUrl=applicationUrl?applicationUrl:window.location.toString().substringBeforeLast("/").substringBeforeLast("/"); + feedsUrl+="/feeds/"+repositoryId; + + + if(repositoryId){ + mainContent.find("#selected_repository" ).html($("#selected_repository_tmpl" ) + .tmpl({repositories:data,selected:repositoryId,feedsUrl:feedsUrl})); + } else { + mainContent.find("#selected_repository" ).html($("#selected_repository_tmpl" ) + .tmpl({repositories:data,selected:'',feedsUrl:null})); + } + + mainContent.find("#browse_artifact_detail" ).hide(); + mainContent.find("#browse_result").hide(); + mainContent.find("#main_browse_result_content").hide("slide", {}, 300,function(){ + mainContent.find("#browse_breadcrumb").html(smallSpinnerImg()); + mainContent.find("#browse_artifact").show(); + mainContent.find("#browse_artifact").html(mediumSpinnerImg()); + mainContent.find("#main_browse_result_content").show(); + var metadataUrl="restServices/archivaServices/browseService/projectVersionMetadata/"+encodeURIComponent(groupId)+"/"+encodeURIComponent(artifactId); + var versionsListUrl="restServices/archivaServices/browseService/versionsList/"+encodeURIComponent(groupId)+"/"+encodeURIComponent(artifactId); + var selectedRepo=getSelectedBrowsingRepository(); + if (selectedRepo){ + metadataUrl+="?repositoryId="+encodeURIComponent(selectedRepo); + versionsListUrl+="?repositoryId="+encodeURIComponent(selectedRepo); + } + $.ajax(metadataUrl, { + type: "GET", + dataType: 'json', + success: function(data) { + artifactDetailViewModel.projectVersionMetadata=mapProjectVersionMetadata(data); + $.ajax(versionsListUrl, { + type: "GET", + dataType: 'json', + success: function(data) { + artifactDetailViewModel.versions=ko.observableArray( mapVersionsList(data)); + ko.applyBindings(artifactDetailViewModel,mainContent.find("#browse_artifact").get(0)); + ko.applyBindings(artifactDetailViewModel,mainContent.find("#browse_breadcrumb").get(0)); + + } + }); + } + }); + }); + }}) + }); + + } + + browseRoot=function(){ + var selectedRepo=getSelectedBrowsingRepository(); + + if(selectedRepo) { + window.sammyArchivaApplication.setLocation("#browse~"+selectedRepo); + } else { + window.sammyArchivaApplication.setLocation("#browse"); + } + } + + /** + * call from menu entry to display root level + * @param freshView redisplay everything + * @param repositoryId if any repository selected + */ + displayBrowse=function(freshView,repositoryId){ + screenChange(); + var mainContent = $("#main-content"); + if(freshView){ + mainContent.html($("#browse-tmpl" ).tmpl()); + } + mainContent.find("#browse_artifact_detail").hide(); + mainContent.find("#browse_artifact" ).hide(); + mainContent.find("#browse_result").html(mediumSpinnerImg()); + + + userRepositoriesCall( + function(data) { + + $.ajax({ + url: "restServices/archivaServices/archivaAdministrationService/applicationUrl", + type: "GET", + dataType: 'text', + success: function(applicationUrl){ + + var feedsUrl=applicationUrl?applicationUrl:window.location.toString().substringBeforeLast("/").substringBeforeLast("/"); + feedsUrl+="/feeds/"+repositoryId; + + + mainContent.find("#selected_repository" ).html($("#selected_repository_tmpl" ) + .tmpl({repositories:data,selected:repositoryId,feedsUrl:feedsUrl})); + var url="restServices/archivaServices/browseService/rootGroups"; + if(repositoryId){ + url+="?repositoryId="+repositoryId; + } + $.ajax(url, { + type: "GET", + dataType: 'json', + success: function(data) { + var browseResultEntries = mapBrowseResultEntries(data); + var browseViewModel = new BrowseViewModel(browseResultEntries,null,null,repositoryId); + ko.applyBindings(browseViewModel,mainContent.find("#browse_breadcrumb").get(0)); + ko.applyBindings(browseViewModel,mainContent.find("#browse_result").get(0)); + enableAutocompleBrowse(); + } + }); + + }} + ) + + } + ) + + } + + changeBrowseRepository=function(){ + var selectedRepository=getSelectedBrowsingRepository(); + // #browse~internal/org.apache.maven + // or #artifact~snapshots/org.apache.maven.plugins/maven-compiler-plugin + var currentHash=window.location.hash; + $.log("currentHash:"+currentHash); + var newLocation = currentHash.substringBeforeFirst("/"); + // maybe the current hash contains a repositoryId so remove it + if (newLocation.indexOf("~")>-1){ + newLocation=currentHash.substringBeforeFirst("~"); + } + if (selectedRepository){ + newLocation+="~"+selectedRepository; + } + newLocation += currentHash.substringAfterFirst("/"); + // do we have extra path after repository ? + + $.log("changeBrowseRepository:"+newLocation); + window.sammyArchivaApplication.setLocation(newLocation); + } + + getSelectedBrowsingRepository=function(){ + var selectedOption=$("#main-content").find("#select_browse_repository").find("option:selected" ); + if (selectedOption.length>0){ + var repoId=selectedOption.val(); + return repoId; + } + return ""; + } + + enableAutocompleBrowse=function(groupId){ + $("#select_browse_repository" ).select2({width: "resolve"}); + // browse-autocomplete + var url="restServices/archivaServices/browseService/rootGroups"; + if (groupId){ + url="restServices/archivaServices/browseService/browseGroupId/"+encodeURIComponent(groupId); + } + var selectedRepo=getSelectedBrowsingRepository(); + if (selectedRepo){ + url+="?repositoryId="+encodeURIComponent(selectedRepo); + } + $( "#main-content").find("#browse-autocomplete" ).autocomplete({ + minLength: 2, + source: function(request, response){ + var query = ""; + if (request.term.indexOf('.')<0&&!groupId){ + // try with rootGroups then filtered + $.get(url, + function(data) { + var browseResultEntries = mapBrowseResultEntries(data); + + var filetered = []; + for(var i=0;i<browseResultEntries.length;i++){ + if (browseResultEntries[i].name.startsWith(request.term)){ + if (groupId){ + $.log("groupId:"+groupId+",browseResultEntry.name:"+browseResultEntries[i].name); + if (browseResultEntries[i].name.startsWith(groupId)) { + filetered.push(browseResultEntries[i]); + } + + } else { + filetered.push(browseResultEntries[i]); + } + } + } + response(filetered); + + } + ); + return; + } + var dotEnd=request.term.endsWith("."); + // org.apache. requets with org.apache + // org.apa request with org before last dot and filter response with startsWith + if (request.term.indexOf(".")>=0){ + if (dotEnd){ + query= groupId?groupId+'.'+request.term.substring(0, request.term.length-1):request.term.substring(0, request.term.length-1); + } else { + // substring before last + query=groupId?groupId+'.'+request.term.substringBeforeLast("."):request.term.substringBeforeLast("."); + } + } else { + query=groupId?groupId:request.term; + } + var browseUrl="restServices/archivaServices/browseService/browseGroupId/"+encodeURIComponent(query); + var selectedRepo=getSelectedBrowsingRepository(); + if (selectedRepo){ + browseUrl+="?repositoryId="+encodeURIComponent(selectedRepo); + } + $.get(browseUrl, + function(data) { + var browseResultEntries = mapBrowseResultEntries(data); + if (dotEnd){ + response(browseResultEntries); + } else { + var filetered = []; + for(var i=0;i<browseResultEntries.length;i++){ + if (groupId){ + if (browseResultEntries[i].name.startsWith(groupId+'.'+request.term)){ + filetered.push(browseResultEntries[i]); + } + } else { + if (browseResultEntries[i].name.startsWith(request.term)){ + filetered.push(browseResultEntries[i]); + } + } + } + response(filetered); + } + } + ); + }, + select: function( event, ui ) { + $.log("ui.item.label:"+ui.item.name); + if (ui.item.project){ + // value org.apache.maven/maven-archiver + // split this org.apache.maven and maven-archiver + var id=ui.item.name; + var values = id.split("."); + var groupId=""; + for (var i = 0;i<values.length-1;i++){ + groupId+=values[i]; + if (i<values.length-2)groupId+="."; + } + var artifactId=values[values.length-1]; + goToArtifactDetail(groupId,artifactId); + } else { + var selectedRepo=getSelectedBrowsingRepository(); + var location ="#browse"; + if (selectedRepo){ + location+="~"+selectedRepo; + } + location+="/"+ui.item.name; + window.sammyArchivaApplication.setLocation(location); + } + return false; + } + }).data( "autocomplete" )._renderItem = function( ul, item ) { + return $( "<li></li>" ) + .data( "item.autocomplete", item ) + .append( groupId ? "<a>" + item.name.substring(groupId.length+1, item.name.length) + "</a>": "<a>" + item.name + "</a>" ) + .appendTo( ul ); + }; + } + + /** + * + * @param groupId + */ + displayBrowseGroupIdFromAutoComplete=function(groupId){ + clearUserMessages(); + var mainContent = $("#main-content"); + mainContent.find("#browse_result").html(mediumSpinnerImg()); + var parentBrowseViewModel=new BrowseViewModel(null,null,null); + displayGroupDetail(groupId,parentBrowseViewModel,null); + } + + displayBrowseArtifactDetail=function(groupId, artifactId){ + $.log("displayBrowseArtifactDetail"); + window.sammyArchivaApplication.setLocation("#artifact/"+groupId+"/"+artifactId); + } + + mapBrowseResultEntries=function(data){ + $.log("mapBrowseResultEntries"); + if (data.browseResultEntries) { + return $.isArray(data.browseResultEntries) ? + $.map(data.browseResultEntries,function(item){ + return new BrowseResultEntry(item.name, item.project); + } ).sort(function(a, b){return a.name.localeCompare(b.name)}): [data.browseResultEntries]; + } + return []; + } + + BrowseResultEntry=function(name,project){ + this.name=name; + this.project=project; + } + + BreadCrumbEntry=function(groupId,displayValue){ + this.groupId=groupId; + this.displayValue=displayValue; + this.artifactId=null; + this.artifact=false; + this.version=null; + } + mapVersionsList=function(data){ + if (data){ + if (data.versions){ + return $.isArray(data.versions)? $.map(data.versions,function(item){return item}) + :[data.versions]; + } + + } + return []; + } + mapProjectVersionMetadata=function(data){ + if (data){ + var projectVersionMetadata = + new ProjectVersionMetadata(data.id,data.url, + data.name,data.description, + null,null,null,null,null,null,null,data.incomplete); + + if (data.organization){ + projectVersionMetadata.organization=new Organization(data.organization.name,data.organization.url); + } + if (data.issueManagement){ + projectVersionMetadata.issueManagement= + new IssueManagement(data.issueManagement.system,data.issueManagement.url); + } + if (data.scm){ + projectVersionMetadata.scm= + new Scm(data.scm.connection,data.scm.developerConnection,data.scm.url); + } + if (data.ciManagement){ + projectVersionMetadata.ciManagement=new CiManagement(data.ciManagement.system,data.ciManagement.url); + } + if (data.licenses){ + projectVersionMetadata.licenses= + $.isArray(data.licenses) ? $.map(data.licenses,function(item){ + return new License(item.name,item.url); + }):[data.licenses]; + } + if (data.mailingLists){ + var mailingLists = + $.isArray(data.mailingLists) ? $.map(data.mailingLists,function(item){ + return new MailingList(item.mainArchiveUrl,item.otherArchives,item.name,item.postAddress, + item.subscribeAddress,item.unsubscribeAddress); + }):[data.mailingLists]; + projectVersionMetadata.mailingLists=mailingLists; + } + if (data.dependencies){ + var dependencies = + $.isArray(data.dependencies) ? $.map(data.dependencies,function(item){ + return new Dependency(item.classifier,item.optional,item.scope,item.systemPath,item.type, + item.artifactId,item.groupId,item.version); + }):[data.dependencies]; + projectVersionMetadata.dependencies=dependencies; + } + // maven facet currently only for packaging + if(data.facetList){ + if( $.isArray(data.facetList)){ + for (var i=0;i<data.facetList.length;i++){ + if(data.facetList[i].facetId=='org.apache.archiva.metadata.repository.storage.maven2.project'){ + projectVersionMetadata.mavenFacet=new MavenFacet(data.facetList[i].packaging,data.facetList[i].parent); + } + } + } else { + if(data.facetList.facetId=='org.apache.archiva.metadata.repository.storage.maven2.project'){ + projectVersionMetadata.mavenFacet=new MavenFacet(data.facetList.packaging,data.facetList.parent); + } + } + } + return projectVersionMetadata; + } + return new ProjectVersionMetadata(); + } + + MavenFacet=function(packaging,parent){ + this.packaging=packaging; + if(parent){ + this.parent={groupId:parent.groupId,artifactId:parent.artifactId,version:parent.version}; + } + + } + + ProjectVersionMetadata=function(id,url,name,description,organization,issueManagement,scm,ciManagement,licenses, + mailingLists,dependencies,incomplete){ + // private String id; + this.id=id; + + // private String url; + this.url=url + + //private String name; + this.name=name; + + //private String description; + this.description=description; + + //private Organization organization; + this.organization=organization; + + //private IssueManagement issueManagement; + this.issueManagement=issueManagement; + + //private Scm scm; + this.scm=scm; + + //private CiManagement ciManagement; + this.ciManagement=ciManagement; + + //private List<License> licenses = new ArrayList<License>(); + this.licenses=licenses; + + //private List<MailingList> mailingLists = new ArrayList<MailingList>(); + this.mailingLists=mailingLists; + + //private List<Dependency> dependencies = new ArrayList<Dependency>(); + this.dependencies=dependencies; + + //private boolean incomplete; + this.incomplete=incomplete; + + this.mavenFacet=null; + + } + + Organization=function(name,url){ + //private String name; + this.name=name; + + //private String url; + this.url=url; + } + + IssueManagement=function(system,url) { + //private String system; + this.system=system; + + //private String url; + this.url=url; + } + + Scm=function(connection,developerConnection,url) { + //private String connection; + this.connection=connection; + + //private String developerConnection; + this.developerConnection=developerConnection; + + //private String url; + this.url=url; + } + + CiManagement=function(system,url) { + //private String system; + this.system=system; + + //private String url; + this.url=url; + } + + License=function(name,url){ + this.name=name; + this.url=url; + } + + MailingList=function(mainArchiveUrl,otherArchives,name,postAddress,subscribeAddress,unsubscribeAddress){ + //private String mainArchiveUrl; + this.mainArchiveUrl=mainArchiveUrl; + + //private List<String> otherArchives; + this.otherArchives=otherArchives; + + //private String name; + this.name=name; + + //private String postAddress; + this.postAddress=postAddress; + + //private String subscribeAddress; + this.subscribeAddress=subscribeAddress; + + //private String unsubscribeAddress; + this.unsubscribeAddress=unsubscribeAddress; + } + + Dependency=function(classifier,optional,scope,systemPath,type,artifactId,groupId,version){ + var self=this; + //private String classifier; + this.classifier=classifier; + + //private boolean optional; + this.optional=optional; + + //private String scope; + this.scope=scope; + + //private String systemPath; + this.systemPath=systemPath; + + //private String type; + this.type=type; + + //private String artifactId; + this.artifactId=artifactId; + + //private String groupId; + this.groupId=groupId; + + //private String version; + this.version=version; + + this.crumbEntries=function(){ + return calculateCrumbEntries(self.groupId,self.artifactId,self.version); + } + + } + + //----------------------------------------- + // search part + //----------------------------------------- + Artifact=function(context,url,groupId,artifactId,repositoryId,version,prefix,goals,bundleVersion,bundleSymbolicName, + bundleExportPackage,bundleExportService,bundleDescription,bundleName,bundleLicense,bundleDocUrl, + bundleImportPackage,bundleRequireBundle,classifier,packaging,fileExtension,size){ + + var self=this; + + //private String context; + this.context=context; + + //private String url; + this.url=url; + + //private String groupId; + this.groupId=groupId; + + //private String artifactId; + this.artifactId=artifactId; + + //private String repositoryId; + this.repositoryId=repositoryId; + + //private String version; + this.version=version; + + //Plugin goal prefix (only if packaging is "maven-plugin") + //private String prefix; + this.prefix=prefix; + + //Plugin goals (only if packaging is "maven-plugin") + //private List<String> goals; + this.goals=goals; + + //private String bundleVersion; + this.bundleVersion=bundleVersion; + + // contains osgi metadata Bundle-SymbolicName if available + //private String bundleSymbolicName; + this.bundleSymbolicName=bundleSymbolicName; + + //contains osgi metadata Export-Package if available + //private String bundleExportPackage; + this.bundleExportPackage=bundleExportPackage; + + //contains osgi metadata Export-Service if available + //private String bundleExportService; + this.bundleExportService=bundleExportService; + + ///contains osgi metadata Bundle-Description if available + //private String bundleDescription; + this.bundleDescription=bundleDescription; + + // contains osgi metadata Bundle-Name if available + //private String bundleName; + this.bundleName=bundleName; + + //contains osgi metadata Bundle-License if available + //private String bundleLicense; + this.bundleLicense=bundleLicense; + + ///contains osgi metadata Bundle-DocURL if available + //private String bundleDocUrl; + this.bundleDocUrl=bundleDocUrl; + + // contains osgi metadata Import-Package if available + //private String bundleImportPackage; + this.bundleImportPackage=bundleImportPackage; + + ///contains osgi metadata Require-Bundle if available + //private String bundleRequireBundle; + this.bundleRequireBundle=bundleRequireBundle; + + //private String classifier; + this.classifier=classifier; + + //private String packaging; + this.packaging=packaging; + + //file extension of the artifact + //private String fileExtension; + this.fileExtension=fileExtension; + + this.size=size; + + this.crumbEntries=function(){ + return calculateCrumbEntries(self.groupId,self.artifactId,self.version); + } + + } + + calculateCrumbEntries=function(groupId,artifactId,version){ + var splitted = groupId.split("."); + var breadCrumbEntries=[]; + var curGroupId=""; + for (var i=0;i<splitted.length;i++){ + curGroupId+=splitted[i]; + breadCrumbEntries.push(new BreadCrumbEntry(curGroupId,splitted[i])); + curGroupId+="." + } + var crumbEntryArtifact=new BreadCrumbEntry(groupId,artifactId); + crumbEntryArtifact.artifactId=artifactId; + crumbEntryArtifact.artifact=true; + breadCrumbEntries.push(crumbEntryArtifact); + + var crumbEntryVersion=new BreadCrumbEntry(groupId,version); + crumbEntryVersion.artifactId=artifactId; + crumbEntryVersion.artifact=false; + crumbEntryVersion.version=version; + breadCrumbEntries.push(crumbEntryVersion); + + return breadCrumbEntries; + } + + mapArtifacts=function(data){ + if (data){ + return $.isArray(data)? $.map(data,function(item){return mapArtifact(item)}) : [data]; + } + return []; + } + + mapArtifact=function(data){ + if(data){ + return new Artifact(data.context,data.url,data.groupId,data.artifactId,data.repositoryId,data.version,data.prefix, + data.goals,data.bundleVersion,data.bundleSymbolicName, + data.bundleExportPackage,data.bundleExportService,data.bundleDescription,data.bundleName, + data.bundleLicense,data.bundleDocUrl, + data.bundleImportPackage,data.bundleRequireBundle,data.classifier,data.packaging,data.fileExtension,data.size); + } + return null; + } + + SearchRequest=function(){ + + this.queryTerms=ko.observable(); + + //private String groupId; + this.groupId=ko.observable(); + + //private String artifactId; + this.artifactId=ko.observable(); + + //private String version; + this.version=ko.observable(); + + //private String packaging; + this.packaging=ko.observable(); + + //private String className; + this.className=ko.observable(); + + //private List<String> repositories = new ArrayList<String>(); + this.repositories=ko.observableArray([]); + + //private String bundleVersion; + this.bundleVersion=ko.observable(); + + //private String bundleSymbolicName; + this.bundleSymbolicName=ko.observable(); + + //private String bundleExportPackage; + this.bundleExportPackage=ko.observable(); + + //private String bundleExportService; + this.bundleExportService=ko.observable(); + + this.bundleImportPackage=ko.observable(); + + this.bundleRequireBundle=ko.observable(); + + //private String classifier; + this.classifier=ko.observable(); + + //private boolean includePomArtifacts = false; + this.includePomArtifacts=ko.observable(false); + + this.classifier=ko.observable(); + } + + applyAutocompleteOnHeader=function(property,resultViewModel){ + $( "#main-content").find("#search-filter-auto-"+property ).autocomplete({ + minLength: 0, + source: function(request, response){ + var founds=[]; + $(resultViewModel.artifacts()).each(function(idx,artifact){ + if(artifact[property] && artifact[property].startsWith(request.term)){ + founds.push(artifact[property]); + } + }); + response(unifyArray(founds,true)); + }, + select: function( event, ui ) { + $.log("property:"+property+','+ui.item.value); + var artifacts=[]; + $(resultViewModel.artifacts()).each(function(idx,artifact){ + if(artifact[property] && artifact[property].startsWith(ui.item.value)){ + artifacts.push(artifact); + } + }); + $.log("property:"+property+','+ui.item.value+",size:"+artifacts.length); + resultViewModel.artifacts(artifacts); + return false; + } + }); + } + + /** + * search results view model: display a grid with autocomplete filtering on grid headers + * @param artifacts + */ + ResultViewModel=function(artifacts){ + var self=this; + this.originalArtifacts=artifacts; + this.artifacts=ko.observableArray(artifacts); + this.gridViewModel = new ko.simpleGrid.viewModel({ + data: self.artifacts, + columns: [ + { + headerText: $.i18n.prop('search.artifact.results.groupId'), + rowText: "groupId", + id: "groupId" + }, + { + headerText: $.i18n.prop('search.artifact.results.artifactId'), + rowText: "artifactId", + id: "artifactId" + }, + { + headerText: $.i18n.prop('search.artifact.results.version'), + rowText: "version", + id: "version" + }, + { + headerText: $.i18n.prop('search.artifact.results.classifier'), + rowText: "classifier", + id: "classifier" + } + ], + pageSize: 10, + gridUpdateCallBack: function(){ + applyAutocompleteOnHeader('groupId',self); + applyAutocompleteOnHeader('artifactId',self); + applyAutocompleteOnHeader('version',self); + applyAutocompleteOnHeader('classifier',self); + } + }); + + groupIdView=function(artifact){ + displayBrowseGroupId(artifact.groupId); + } + artifactIdView=function(artifact){ + displayBrowseArtifactDetail(artifact.groupId,artifact.artifactId,null,null); + } + artifactDetailView=function(artifact){ + + var selectedRepo=getSelectedBrowsingRepository(); + + var location ="#artifact"; + if (selectedRepo){ + location+="~"+selectedRepo; + } + location+="/"+artifact.groupId+"/"+artifact.artifactId+"/"+artifact.version; + + if(artifact.classifier){ + location+="/"+artifact.classifier; + } + + window.sammyArchivaApplication.setLocation(location); + } + } + + generalDisplayArtifactDetailsVersionView=function(groupId,artifactId,version,repositoryId,afterCallbackFn){ + var mainContent=$("#main-content"); + mainContent.html($("#browse-tmpl" ).tmpl()); + mainContent.find("#browse_result" ).hide(); + mainContent.find("#browse_artifact_detail").show(); + mainContent.find("#browse_artifact_detail").html(mediumSpinnerImg()); + mainContent.find("#browse_breadcrumb" ).show(); + mainContent.find("#browse_breadcrumb" ).html(mediumSpinnerImg()); + + userRepositoriesCall( + function(data) { + $.ajax({ + url: "restServices/archivaServices/archivaAdministrationService/applicationUrl", + type: "GET", + dataType: 'text', + success: function(applicationUrl){ + + var feedsUrl=applicationUrl?applicationUrl:window.location.toString().substringBeforeLast("/").substringBeforeLast("/"); + feedsUrl+="/feeds/"+repositoryId; + mainContent.find("#selected_repository" ).html($("#selected_repository_tmpl" ) + .tmpl({repositories:data,selected:repositoryId,feedsUrl:feedsUrl})); + var artifactVersionDetailViewModel=new ArtifactVersionDetailViewModel(groupId,artifactId,version,repositoryId); + artifactVersionDetailViewModel.display(afterCallbackFn); + }}) + } + ); + + } + + userRepositoriesCall=function(successCallbackFn){ + $.ajax("restServices/archivaServices/browseService/userRepositories", { + type: "GET", + dataType: 'json', + success: function(data) { + successCallbackFn(data); + } + }); + } + + /** + * View model used for search response and filtering + */ + SearchViewModel=function(){ + var self=this; + var mainContent=$("#main-content"); + this.searchRequest=ko.observable(new SearchRequest()); + this.observableRepoIds=ko.observableArray([]); + this.selectedRepoIds=[]; + this.resultViewModel=new ResultViewModel([]); + basicSearch=function(){ + var queryTerm=this.searchRequest().queryTerms(); + if ($.trim(queryTerm).length<1){ + var errorList=[{ + message: $.i18n.prop("search.artifact.search.form.terms.empty"), + element: $("#main-content").find("#search-basic-form").find("#search-terms" ).get(0) + }]; + customShowError("#main-content #search-basic-form", null, null, errorList); + return; + } else { + // cleanup previours error message + customShowError("#main-content #search-basic-form", null, null, []); + } + var location="#basicsearch"; + + self.selectedRepoIds=[]; + mainContent.find("#search-basic-repositories" ) + .find(".chzn-choices li span").each(function(i,span){ + self.selectedRepoIds.push($(span).html()); + } + ); + + if (self.selectedRepoIds.length>0){ + $.log("selectedRepoIds:"+self.selectedRepoIds.length); + $(self.selectedRepoIds).each(function(index, Element){ + location+="~"+self.selectedRepoIds[index]; + }); + } + location+="/"+queryTerm; + window.sammyArchivaApplication.setLocation(location); + } + + this.externalBasicSearch=function(){ + var queryTerm=this.searchRequest().queryTerms(); + self.search("restServices/archivaServices/searchService/quickSearchWithRepositories",this.searchRequest().repositories); + } + + /** + * use from autocomplete search + */ + this.externalAdvancedSearch=function(){ + this.search("restServices/archivaServices/searchService/searchArtifacts"); + } + advancedSearch=function(){ + var location="#advancedsearch"; + + self.selectedRepoIds=[]; + mainContent.find("#search-basic-repositories" ) + .find(".chzn-choices li span").each(function(i,span){ + self.selectedRepoIds.push($(span).html()); + } + ); + + if (self.selectedRepoIds.length>0){ + $.log("selectedRepoIds:"+self.selectedRepoIds.length); + $(self.selectedRepoIds).each(function(index, Element){ + location+="~"+self.selectedRepoIds[index]; + }); + } + location+="/"; + if(self.searchRequest().groupId()){ + location+=self.searchRequest().groupId(); + }/*else{ + location+='~'; + }*/ + if(self.searchRequest().artifactId()){ + location+='~'+self.searchRequest().artifactId(); + }else{ + location+='~'; + } + if(self.searchRequest().version()){ + location+='~'+self.searchRequest().version(); + }else{ + location+='~'; + } + if(self.searchRequest().classifier()){ + location+='~'+self.searchRequest().classifier(); + }else{ + location+='~'; + } + if(self.searchRequest().packaging()){ + location+='~'+self.searchRequest().packaging(); + }else{ + location+='~'; + } + if(self.searchRequest().className()){ + location+='~'+self.searchRequest().className(); + }else{ + location+='~'; + } + + $.log("location:"+location); + window.sammyArchivaApplication.setLocation(location); + } + removeFilter=function(){ + $.log("removeFilter:"+self.resultViewModel.originalArtifacts.length); + self.resultViewModel.artifacts(self.resultViewModel.originalArtifacts); + } + this.search=function(url,repositoriesIds){ + + var searchResultsGrid=mainContent.find("#search-results" ).find("#search-results-grid" ); + mainContent.find("#btn-basic-search" ).button("loading"); + mainContent.find("#btn-advanced-search" ).button("loading"); + var userMessages=$("#user-messages"); + userMessages.html(mediumSpinnerImg()); + if (repositoriesIds){ + self.selectedRepoIds=repositoriesIds; + } else { + self.selectedRepoIds=[]; + mainContent.find("#search-basic-repositories" ) + .find(".chzn-choices li span").each(function(i,span){ + self.selectedRepoIds.push($(span).html()); + } + ); + } + this.searchRequest().repositories=this.selectedRepoIds; + $.ajax(url, + { + type: "POST", + data: ko.toJSON(this.searchRequest), + contentType: 'application/json', + dataType: 'json', + success: function(data) { + clearUserMessages(); + var artifacts=mapArtifacts(data); + $.log("search#ajax call success:artifacts.length:"+artifacts.length); + if (artifacts.length<1){ + displayWarningMessage( $.i18n.prop("search.artifact.noresults")); + return; + } else { + self.resultViewModel.originalArtifacts=artifacts; + $.log("search#ajax call success:self.resultViewModel.originalArtifacts:"+self.resultViewModel.originalArtifacts.length); + self.resultViewModel.artifacts(artifacts); + if (!searchResultsGrid.attr("data-bind")){ + $.log('!searchResultsGrid.attr("data-bind")'); + searchResultsGrid.attr("data-bind", + "simpleGrid: gridViewModel,simpleGridTemplate:'search-results-view-grid-tmpl',pageLinksId:'search-results-view-grid-pagination'"); + ko.applyBindings(self.resultViewModel,searchResultsGrid.get(0)); + ko.applyBindings(self,mainContent.find("#remove-filter-id" ).get(0)); + mainContent.find("#search-result-number-div").attr("data-bind","template:{name:'search-result-number-div-tmpl'}"); + ko.applyBindings(self,mainContent.find("#search-result-number-div" ).get(0)); + } + + activateSearchResultsTab(); + } + }, + error: function(data) { + var res = $.parseJSON(data.responseText); + displayRestError(res); + }, + complete:function() { + mainContent.find("#btn-basic-search" ).button("reset"); + mainContent.find("#btn-advanced-search" ).button("reset"); + removeMediumSpinnerImg(userMessages); + } + } + ); + } + + } + + activateSearchResultsTab=function(){ + var mainContent=$("#main-content"); + mainContent.find("#search-form-collapse").removeClass("active"); + mainContent.find("#search-results").addClass("active"); + + mainContent.find("#search-form-collapse-li").removeClass("active"); + mainContent.find("#search-results-li" ).addClass("active"); + + } + + /** + * display a search result (collection of Artifacts) in a grid + * see template with id #search-artifacts-div-tmpl + * @param successCallbackFn can be a callback function called on success getting observable repositories. + * @param searchViewModelCurrent model to reuse if not null whereas a new one is created. + */ + displaySearch=function(successCallbackFn,searchViewModelCurrent){ + screenChange(); + var mainContent=$("#main-content"); + mainContent.html(mediumSpinnerImg()); + $.ajax("restServices/archivaServices/searchService/observableRepoIds", { + type: "GET", + dataType: 'json', + success: function(data) { + mainContent.html($("#search-artifacts-div-tmpl" ).tmpl()); + var searchViewModel; + if (searchViewModelCurrent){ + $.log("searchViewModelCurrent not null"); + searchViewModel=searchViewModelCurrent + }else { + $.log("searchViewModelCurrent null"); + searchViewModel=new SearchViewModel(); + } + var repos=mapStringList(data); + $.log("repos:"+repos); + searchViewModel.observableRepoIds(repos); + ko.applyBindings(searchViewModel,mainContent.find("#search-artifacts-div").get(0)); + mainContent.find("#search-basic-repositories-select" ).select2(); + if (successCallbackFn && $.isFunction(successCallbackFn)) successCallbackFn(); + } + }); + + } + + + +});
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/startup.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/startup.js new file mode 100644 index 000000000..65cb7a4cc --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/startup.js @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +define("startup",["jquery","sammy","utils"], +function(jquery,sammy,utils) { + + // define a container object with various datas + window.archivaModel = {}; + + //$.log("devMode:"+window.archivaDevMode); + + + + // no cache for ajax queries as we get datas from servers so preventing caching !! + jQuery.ajaxSetup( { + cache: false,//!window.archivaDevMode + dataType: 'json', + statusCode: { + 403: function() { + removeSmallSpinnerImg(); + removeMediumSpinnerImg("#main-content"); + clearUserMessages(); + displayErrorMessage($.i18n.prop('authz.karma.needed')); + userLogged(function(user){ + userLoggedCallbackFn(user); + },function(){ + $.log("not logged"); + loginBox(); + }); + }, + 500: function(data){ + $.log("error 500:"+data.responseText); + removeSmallSpinnerImg(); + removeMediumSpinnerImg("#main-content"); + clearUserMessages(); + displayRestError($.parseJSON(data.responseText)); + } + } + }); + +});
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/utils.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/utils.js new file mode 100644 index 000000000..76963b69a --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/archiva/utils.js @@ -0,0 +1,511 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +require(["jquery","jquery.tmpl","i18n","knockout"], function(jquery,jqueryTmpl,i18n,ko) { + + loadi18n=function(loadCallback){ + $.log("loadi18n"); + var browserLang = usedLang(); + $.log("use browserLang:"+browserLang); + + var options = { + cache:false, + mode: 'map', + encoding:'utf-8', + callback: loadCallback + }; + loadAndParseFile("restServices/archivaServices/commonServices/getAllI18nResources?locale="+browserLang,options ); + } + + /** + * log message in the console + */ + $.log = (function(message) { + if ( !window.archivaJavascriptLog ){ + return; + } + Sammy.log(message); + /*return; + if (typeof window.console != 'undefined' && typeof window.console.log != 'undefined') { + console.log(message); + } else { + // do nothing no console + }*/ + }); + + /** + * return value of a param in the url + * @param name + */ + $.urlParam = function(name){ + var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href); + if (results) { + return results[1] || 0; + } + return null; + } + + usedLang=function(){ + var browserLang = $.i18n.browserLang(); + var requestLang = $.urlParam('request_lang'); + if (requestLang) { + browserLang=requestLang; + } + return browserLang; + } + + /** + * display a success message + * @param text the success text + * @param idToAppend the id to append the success box + */ + displaySuccessMessage=function(text,idToAppend){ + var textId = idToAppend ? $("#"+idToAppend) : $("#user-messages"); + $.tmpl($("#alert-message-success").html(), { "message" : text }).appendTo( textId ); + $(textId).focus(); + } + + /** + * display an error message + * @param text the success text + * @param idToAppend the id to append the success box + */ + displayErrorMessage=function(text,idToAppend){ + var textId = idToAppend ? $("#"+idToAppend) : $("#user-messages"); + $.tmpl($("#alert-message-error").html(), { "message" : text }).appendTo( textId ); + $(textId).focus(); + } + + /** + * display a warning message + * @param text the success text + * @param idToAppend the id to append the success box + */ + displayWarningMessage=function(text,idToAppend){ + var textId = idToAppend ? $("#"+idToAppend) : $("#user-messages"); + $.tmpl($("#alert-message-warning").html(), { "message" : text }).appendTo( textId ); + $(textId).focus(); + } + + displayInfoMessage=function(text,idToAppend){ + var textId = idToAppend ? $("#"+idToAppend) : $("#user-messages"); + $.tmpl($("#alert-message-info").html(), { "message" : text }).appendTo( textId ); + $(textId).focus(); + } + + getUrlHash=function(){ + var matches = window.location.toString().match(/^[^#]*(#.+)$/); + return matches ? matches[1] : null; + } + + refreshContent=function(){ + var currentHash=getUrlHash(); + $.log("getUrlHash:"+currentHash); + window.sammyArchivaApplication.runRoute('get',currentHash); + + } + + /** + * clear #main-content and call clearUserMessages + */ + screenChange=function(){ + var mainContent=$("#main-content"); + mainContent.empty(); + mainContent.removeAttr("data-bind"); + $("#body_content" ).find(".popover" ).hide(); + clearUserMessages(); + if(window.archivaModel.adminExists==false){ + displayErrorMessage($.i18n.prop("admin.creation.mandatory")); + } + + } + + /** + * clear content of id if none clear content of #user-messages + * @param idToAppend + */ + clearUserMessages=function(idToAppend){ + var textId = idToAppend ? $("#"+idToAppend) : $("#user-messages"); + $(textId).empty(); + } + + /** + * clear all input text and password found in the the selector + * @param selectorStr + */ + clearForm=function(selectorStr){ + $(selectorStr).find("input[type='text']").each(function(ele){ + $(this).val(""); + }); + $(selectorStr).find("input[type='password']").each(function(ele){ + $(this).val(""); + }); + + } + + /** + * open a confirm dialog based on bootstrap modal + * @param okFn callback function to call on ok confirm + * @param okMessage message in the ok button + * @param cancelMessage message in the cancel button + * @param title title of the modal box + * @param bodyText html content of the modal box + */ + openDialogConfirm=function(okFn, okMessage, cancelMessage, title,bodyText){ + var dialogCancel=$("#dialog-confirm-modal-cancel"); + if (window.modalConfirmDialog==null) { + window.modalConfirmDialog = $("#dialog-confirm-modal").modal(); + window.modalConfirmDialog.bind('hidden', function () { + $("#dialog-confirm-modal-header-title").empty(); + $("#dialog-confirm-modal-body-text").empty(); + }) + dialogCancel.on("click", function(){ + window.modalConfirmDialog.modal('hide'); + }); + } + $("#dialog-confirm-modal-header-title").html(title); + $("#dialog-confirm-modal-body-text").html(bodyText); + var dialogConfirmModalOk=$("#dialog-confirm-modal-ok"); + if (okMessage){ + dialogConfirmModalOk.html(okMessage); + } + if (cancelMessage){ + dialogCancel.html(cancelMessage); + } + window.modalConfirmDialog.modal('show'); + + // unbind previous events !! + + dialogConfirmModalOk.off( ); + dialogConfirmModalOk.on("click", okFn); + + } + + /** + * return a small spinner html img element + */ + smallSpinnerImg=function(){ + return "<img id=\"small-spinner\" src=\"images/small-spinner.gif\"/>"; + }; + + removeSmallSpinnerImg=function(){ + $("#small-spinner").remove(); + } + + removeMediumSpinnerImg=function(){ + $("#medium-spinner").remove(); + } + + removeMediumSpinnerImg=function(selector){ + if (typeof selector == 'string') { + $(selector).find("#medium-spinner").remove(); + } else { + selector.find("#medium-spinner").remove(); + } + + } + + mediumSpinnerImg=function(){ + return "<img id=\"medium-spinner\" src=\"images/medium-spinner.gif\"/>"; + }; + + closeDialogConfirm=function(){ + window.modalConfirmDialog.modal('hide'); + } + + mapStringArray=function(data){ + if (data) { + if ($.isArray(data)){ + return $.map(data,function(item){ + return item; + }); + } else { + return new Array(data); + } + } + return null; + } + + /** + * display redback error from redback json error response + * {"redbackRestError":{"errorMessages":{"args":1,"errorKey":"user.password.violation.numeric"}}} + * @param obj + * @param idToAppend + */ + displayRedbackError=function(obj,idToAppend) { + if ($.isArray(obj.errorMessages)) { + $.log("displayRedbackError with array"); + for(var i=0; i<obj.errorMessages.length; i++ ) { + if(obj.errorMessages[i].errorKey) { + displayErrorMessage($.i18n.prop( obj.errorMessages[i].errorKey, obj.errorMessages[i].args ),idToAppend); + } + if(obj.errorMessages[i].message) { + displayErrorMessage(obj.errorMessages[i].message,idToAppend); + } + } + } else { + displayErrorMessage($.i18n.prop( obj.errorMessages.errorKey, obj.errorMessages.args ),idToAppend); + } + } + + /* + * generic function to display error return by rest service + * if fieldName is here the function will try to find a field with this name and add a span on it + * if not error is displayed in #user-messages div + */ + displayRestError=function(data,idToAppend){ + $.log("displayRestError"); + // maybe data is just the response so test if if we have a responseText and transform it to json + if(data.responseText){ + data= $.parseJSON(data.responseText); + } + if (data.redbackRestError){ + displayRedbackError(archivaRestError,idToAppend) + } + // if we have the fieldName display error on it + if (data && data.fieldName){ + var mainContent=$("#main-content"); + + if (mainContent.find("#"+data.fieldName)){ + var message=null; + if (data.errorKey) { + message=$.i18n.prop('data.errorKey'); + } else { + message=data.errorMessage; + } + mainContent.find("div.clearfix" ).removeClass( "error" ); + mainContent.find("span.help-inline" ).remove(); + mainContent.find("#"+data.fieldName).parents( "div.clearfix" ).addClass( "error" ); + mainContent.find("#"+data.fieldName).parent().append( "<span class=\"help-inline\">" + message + "</span>" ); + return; + } + // we don't have any id with this fieldName so continue + } + + if (data.errorKey && data.errorKey.length>0){ + displayErrorMessage($.i18n.prop( data.errorKey ),idToAppend); + } else if (data.errorMessages){ + $.each(data.errorMessages, function(index, value) { + if(data.errorMessages[index].errorKey) { + displayErrorMessage( $.i18n.prop(data.errorMessages[index].errorKey,data.errorMessages[index].args?data.errorMessages[index].args:null),idToAppend); + } + }); + } else { + $.log("print data.errorMessage:"+data.errorMessage); + displayErrorMessage(data.errorMessage,idToAppend); + } + + } + + /** + * used by validation error to customize error display in the ui + * @param selector + * @param validator + * @param errorMap + * @param errorList + */ + customShowError=function(selector, validator, errorMap, errorList) { + removeValidationErrorMessages(selector); + for ( var i = 0; errorList[i]; i++ ) { + var error = errorList[i]; + if (typeof selector == 'string') { + var field = $(selector).find("#"+error.element.id); + } else { + var field = selector.find("#"+error.element.id); + } + field.parents( "div.control-group" ).addClass( "error" ); + field.parent().append( "<span class=\"help-inline\">" + error.message + "</span>" ); + } + } + + removeValidationErrorMessages=function(selector){ + if (typeof selector == 'string') { + $(selector).find("div.control-group" ).removeClass( "error" ); + $(selector).find("span.help-inline").remove(); + } else { + selector.find("div.control-group" ).removeClass( "error" ); + selector.find("span.help-inline").remove(); + } + + } + + appendArchivaVersion=function(){ + return "_archivaVersion="+window.archivaRuntimeInfo.version; + } + + buildLoadJsUrl=function(srcScript){ + return srcScript+"?"+appendArchivaVersion()+"&_"+jQuery.now(); + } + + timestampNoCache=function(){ + if (!window.archivaDevMode){ + return ""; + } + return "&_="+jQuery.now(); + } + + + /** + * mapping for a java Map entry + * @param key + * @param value + * @param subscribeFn if any will be called as subscrible function field + */ + Entry=function(key,value,subscribeFn){ + var self=this; + this.modified=ko.observable(false); + this.modified.subscribe(function(newValue){ + $.log("Entry modified"); + }); + + this.key=ko.observable(key); + this.key.subscribe(function(newValue){ + self.modified(true); + if(subscribeFn){ + subscribeFn(newValue) + } + }); + + this.value=ko.observable(value); + this.value.subscribe(function(newValue){ + self.modified(true); + if(subscribeFn){ + subscribeFn(newValue) + } + }); + + + } + + /** + * map {"strings":["snapshots","internal"]} to an array + * @param data + */ + mapStringList=function(data){ + if (data && data.strings){ + return $.isArray(data.strings) ? + $.map(data.strings,function(item){return item}): [data.strings]; + } + return []; + } + + /** + * return an array with removing duplicate strings + * @param strArray an array of string + * @param sorted to sort or not + */ + unifyArray=function(strArray,sorted){ + var res = []; + $(strArray).each(function(idx,str){ + if ( $.inArray(str,res)<0){ + res.push(str); + } + }); + return sorted?res.sort():res; + } + + goToAnchor=function(anchor){ + var curHref = window.location.href; + curHref=curHref.substringBeforeLast("#"); + window.location.href=curHref+"#"+anchor; + } + + //------------------------------------ + // utils javascript string extensions + //------------------------------------ + + String.prototype.isEmpty = function(str) { + return ($.trim(this ).length < 1); + } + String.prototype.isNotEmpty = function(str) { + return ($.trim(this ).length > 0); + } + + String.prototype.endsWith = function(str) { + return (this.match(str+"$")==str) + } + + String.prototype.startsWith = function(str) { + return (this.match("^"+str)==str) + } + + String.prototype.substringBeforeLast = function(str) { + return this.substring(0,this.lastIndexOf(str)); + } + + String.prototype.substringBeforeFirst = function(str) { + var idx = this.indexOf(str); + if(idx<0){ + return this; + } + return this.substring(0,idx); + } + + String.prototype.substringAfterLast = function(str) { + return this.substring(this.lastIndexOf(str)+1); + } + /** + * + * @param str + * @return {String} if str not found return empty string + */ + String.prototype.substringAfterFirst = function(str) { + var idx = this.indexOf(str); + if (idx<0){ + return ""; + } + return this.substring(idx+str.length); + } + + escapeDot=function(str){ + return str.replace(/\./g,"\\\."); + } + + /** + * select class: + * * .popover-doc: activate popover with html:true and click trigger + * * .tooltip-doc: active tooltip + */ + activatePopoverDoc=function(){ + var mainContent=$("#main-content"); + mainContent.find(".popover-doc" ).popover({html: true, trigger: 'click'}); + /*mainContent.find(".popover-doc" ).on("click",function(){ + $(this).popover("show"); + }); + + mainContent.find(".popover-doc" ).mouseover(function(){ + $(this).popover("destroy"); + });*/ + + mainContent.find(".tooltip-doc" ).tooltip({html: true, trigger: 'hover'}); + } + + //----------------------------------------- + // extends jquery tmpl to support var def + //----------------------------------------- + + $(function() { + $.extend($.tmpl.tag, { + "var": { + open: "var $1;" + } + }); + }); + +});
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/bootstrap.2.2.1.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/bootstrap.2.2.1.js new file mode 100644 index 000000000..c753bd6f8 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/bootstrap.2.2.1.js @@ -0,0 +1,2025 @@ +/* =================================================== + * bootstrap-transition.js v2.2.1 + * http://twitter.github.com/bootstrap/javascript.html#transitions + * =================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* CSS TRANSITION SUPPORT (http://www.modernizr.com/) + * ======================================================= */ + + $(function () { + + $.support.transition = (function () { + + var transitionEnd = (function () { + + var el = document.createElement('bootstrap') + , transEndEventNames = { + 'WebkitTransition' : 'webkitTransitionEnd' + , 'MozTransition' : 'transitionend' + , 'OTransition' : 'oTransitionEnd otransitionend' + , 'transition' : 'transitionend' + } + , name + + for (name in transEndEventNames){ + if (el.style[name] !== undefined) { + return transEndEventNames[name] + } + } + + }()) + + return transitionEnd && { + end: transitionEnd + } + + })() + + }) + +}(window.jQuery);/* ========================================================== + * bootstrap-alert.js v2.2.1 + * http://twitter.github.com/bootstrap/javascript.html#alerts + * ========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* ALERT CLASS DEFINITION + * ====================== */ + + var dismiss = '[data-dismiss="alert"]' + , Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.prototype.close = function (e) { + var $this = $(this) + , selector = $this.attr('data-target') + , $parent + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 + } + + $parent = $(selector) + + e && e.preventDefault() + + $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent()) + + $parent.trigger(e = $.Event('close')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + $parent + .trigger('closed') + .remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent.on($.support.transition.end, removeElement) : + removeElement() + } + + + /* ALERT PLUGIN DEFINITION + * ======================= */ + + $.fn.alert = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('alert') + if (!data) $this.data('alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + $.fn.alert.Constructor = Alert + + + /* ALERT DATA-API + * ============== */ + + $(document).on('click.alert.data-api', dismiss, Alert.prototype.close) + +}(window.jQuery);/* ============================================================ + * bootstrap-button.js v2.2.1 + * http://twitter.github.com/bootstrap/javascript.html#buttons + * ============================================================ + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* BUTTON PUBLIC CLASS DEFINITION + * ============================== */ + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, $.fn.button.defaults, options) + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + , $el = this.$element + , data = $el.data() + , val = $el.is('input') ? 'val' : 'html' + + state = state + 'Text' + data.resetText || $el.data('resetText', $el[val]()) + + $el[val](data[state] || this.options[state]) + + // push to event loop to allow forms to submit + setTimeout(function () { + state == 'loadingText' ? + $el.addClass(d).attr(d, d) : + $el.removeClass(d).removeAttr(d) + }, 0) + } + + Button.prototype.toggle = function () { + var $parent = this.$element.closest('[data-toggle="buttons-radio"]') + + $parent && $parent + .find('.active') + .removeClass('active') + + this.$element.toggleClass('active') + } + + + /* BUTTON PLUGIN DEFINITION + * ======================== */ + + $.fn.button = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('button') + , options = typeof option == 'object' && option + if (!data) $this.data('button', (data = new Button(this, options))) + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) + } + + $.fn.button.defaults = { + loadingText: 'loading...' + } + + $.fn.button.Constructor = Button + + + /* BUTTON DATA-API + * =============== */ + + $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) { + var $btn = $(e.target) + if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') + $btn.button('toggle') + }) + +}(window.jQuery);/* ========================================================== + * bootstrap-carousel.js v2.2.1 + * http://twitter.github.com/bootstrap/javascript.html#carousel + * ========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* CAROUSEL CLASS DEFINITION + * ========================= */ + + var Carousel = function (element, options) { + this.$element = $(element) + this.options = options + this.options.slide && this.slide(this.options.slide) + this.options.pause == 'hover' && this.$element + .on('mouseenter', $.proxy(this.pause, this)) + .on('mouseleave', $.proxy(this.cycle, this)) + } + + Carousel.prototype = { + + cycle: function (e) { + if (!e) this.paused = false + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + return this + } + + , to: function (pos) { + var $active = this.$element.find('.item.active') + , children = $active.parent().children() + , activePos = children.index($active) + , that = this + + if (pos > (children.length - 1) || pos < 0) return + + if (this.sliding) { + return this.$element.one('slid', function () { + that.to(pos) + }) + } + + if (activePos == pos) { + return this.pause().cycle() + } + + return this.slide(pos > activePos ? 'next' : 'prev', $(children[pos])) + } + + , pause: function (e) { + if (!e) this.paused = true + if (this.$element.find('.next, .prev').length && $.support.transition.end) { + this.$element.trigger($.support.transition.end) + this.cycle() + } + clearInterval(this.interval) + this.interval = null + return this + } + + , next: function () { + if (this.sliding) return + return this.slide('next') + } + + , prev: function () { + if (this.sliding) return + return this.slide('prev') + } + + , slide: function (type, next) { + var $active = this.$element.find('.item.active') + , $next = next || $active[type]() + , isCycling = this.interval + , direction = type == 'next' ? 'left' : 'right' + , fallback = type == 'next' ? 'first' : 'last' + , that = this + , e + + this.sliding = true + + isCycling && this.pause() + + $next = $next.length ? $next : this.$element.find('.item')[fallback]() + + e = $.Event('slide', { + relatedTarget: $next[0] + }) + + if ($next.hasClass('active')) return + + if ($.support.transition && this.$element.hasClass('slide')) { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $next.addClass(type) + $next[0].offsetWidth // force reflow + $active.addClass(direction) + $next.addClass(direction) + this.$element.one($.support.transition.end, function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { that.$element.trigger('slid') }, 0) + }) + } else { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger('slid') + } + + isCycling && this.cycle() + + return this + } + + } + + + /* CAROUSEL PLUGIN DEFINITION + * ========================== */ + + $.fn.carousel = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('carousel') + , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option) + , action = typeof option == 'string' ? option : options.slide + if (!data) $this.data('carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.cycle() + }) + } + + $.fn.carousel.defaults = { + interval: 5000 + , pause: 'hover' + } + + $.fn.carousel.Constructor = Carousel + + + /* CAROUSEL DATA-API + * ================= */ + + $(document).on('click.carousel.data-api', '[data-slide]', function (e) { + var $this = $(this), href + , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 + , options = $.extend({}, $target.data(), $this.data()) + $target.carousel(options) + e.preventDefault() + }) + +}(window.jQuery);/* ============================================================= + * bootstrap-collapse.js v2.2.1 + * http://twitter.github.com/bootstrap/javascript.html#collapse + * ============================================================= + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* COLLAPSE PUBLIC CLASS DEFINITION + * ================================ */ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, $.fn.collapse.defaults, options) + + if (this.options.parent) { + this.$parent = $(this.options.parent) + } + + this.options.toggle && this.toggle() + } + + Collapse.prototype = { + + constructor: Collapse + + , dimension: function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + , show: function () { + var dimension + , scroll + , actives + , hasData + + if (this.transitioning) return + + dimension = this.dimension() + scroll = $.camelCase(['scroll', dimension].join('-')) + actives = this.$parent && this.$parent.find('> .accordion-group > .in') + + if (actives && actives.length) { + hasData = actives.data('collapse') + if (hasData && hasData.transitioning) return + actives.collapse('hide') + hasData || actives.data('collapse', null) + } + + this.$element[dimension](0) + this.transition('addClass', $.Event('show'), 'shown') + $.support.transition && this.$element[dimension](this.$element[0][scroll]) + } + + , hide: function () { + var dimension + if (this.transitioning) return + dimension = this.dimension() + this.reset(this.$element[dimension]()) + this.transition('removeClass', $.Event('hide'), 'hidden') + this.$element[dimension](0) + } + + , reset: function (size) { + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + [dimension](size || 'auto') + [0].offsetWidth + + this.$element[size !== null ? 'addClass' : 'removeClass']('collapse') + + return this + } + + , transition: function (method, startEvent, completeEvent) { + var that = this + , complete = function () { + if (startEvent.type == 'show') that.reset() + that.transitioning = 0 + that.$element.trigger(completeEvent) + } + + this.$element.trigger(startEvent) + + if (startEvent.isDefaultPrevented()) return + + this.transitioning = 1 + + this.$element[method]('in') + + $.support.transition && this.$element.hasClass('collapse') ? + this.$element.one($.support.transition.end, complete) : + complete() + } + + , toggle: function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + } + + + /* COLLAPSIBLE PLUGIN DEFINITION + * ============================== */ + + $.fn.collapse = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('collapse') + , options = typeof option == 'object' && option + if (!data) $this.data('collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.collapse.defaults = { + toggle: true + } + + $.fn.collapse.Constructor = Collapse + + + /* COLLAPSIBLE DATA-API + * ==================== */ + + $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) { + var $this = $(this), href + , target = $this.attr('data-target') + || e.preventDefault() + || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 + , option = $(target).data('collapse') ? 'toggle' : $this.data() + $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed') + $(target).collapse(option) + }) + +}(window.jQuery);/* ============================================================ + * bootstrap-dropdown.js v2.2.1 + * http://twitter.github.com/bootstrap/javascript.html#dropdowns + * ============================================================ + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* DROPDOWN CLASS DEFINITION + * ========================= */ + + var toggle = '[data-toggle=dropdown]' + , Dropdown = function (element) { + var $el = $(element).on('click.dropdown.data-api', this.toggle) + $('html').on('click.dropdown.data-api', function () { + $el.parent().removeClass('open') + }) + } + + Dropdown.prototype = { + + constructor: Dropdown + + , toggle: function (e) { + var $this = $(this) + , $parent + , isActive + + if ($this.is('.disabled, :disabled')) return + + $parent = getParent($this) + + isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + $parent.toggleClass('open') + $this.focus() + } + + return false + } + + , keydown: function (e) { + var $this + , $items + , $active + , $parent + , isActive + , index + + if (!/(38|40|27)/.test(e.keyCode)) return + + $this = $(this) + + e.preventDefault() + e.stopPropagation() + + if ($this.is('.disabled, :disabled')) return + + $parent = getParent($this) + + isActive = $parent.hasClass('open') + + if (!isActive || (isActive && e.keyCode == 27)) return $this.click() + + $items = $('[role=menu] li:not(.divider) a', $parent) + + if (!$items.length) return + + index = $items.index($items.filter(':focus')) + + if (e.keyCode == 38 && index > 0) index-- // up + if (e.keyCode == 40 && index < $items.length - 1) index++ // down + if (!~index) index = 0 + + $items + .eq(index) + .focus() + } + + } + + function clearMenus() { + $(toggle).each(function () { + getParent($(this)).removeClass('open') + }) + } + + function getParent($this) { + var selector = $this.attr('data-target') + , $parent + + if (!selector) { + selector = $this.attr('href') + selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 + } + + $parent = $(selector) + $parent.length || ($parent = $this.parent()) + + return $parent + } + + + /* DROPDOWN PLUGIN DEFINITION + * ========================== */ + + $.fn.dropdown = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('dropdown') + if (!data) $this.data('dropdown', (data = new Dropdown(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + $.fn.dropdown.Constructor = Dropdown + + + /* APPLY TO STANDARD DROPDOWN ELEMENTS + * =================================== */ + + $(document) + .on('click.dropdown.data-api touchstart.dropdown.data-api', clearMenus) + .on('click.dropdown touchstart.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) + .on('click.dropdown.data-api touchstart.dropdown.data-api' , toggle, Dropdown.prototype.toggle) + .on('keydown.dropdown.data-api touchstart.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown) + +}(window.jQuery);/* ========================================================= + * bootstrap-modal.js v2.2.1 + * http://twitter.github.com/bootstrap/javascript.html#modals + * ========================================================= + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================= */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* MODAL CLASS DEFINITION + * ====================== */ + + var Modal = function (element, options) { + this.options = options + this.$element = $(element) + .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this)) + this.options.remote && this.$element.find('.modal-body').load(this.options.remote) + } + + Modal.prototype = { + + constructor: Modal + + , toggle: function () { + return this[!this.isShown ? 'show' : 'hide']() + } + + , show: function () { + var that = this + , e = $.Event('show') + + this.$element.trigger(e) + + if (this.isShown || e.isDefaultPrevented()) return + + this.isShown = true + + this.escape() + + this.backdrop(function () { + var transition = $.support.transition && that.$element.hasClass('fade') + + if (!that.$element.parent().length) { + that.$element.appendTo(document.body) //don't move modals dom position + } + + that.$element + .show() + + if (transition) { + that.$element[0].offsetWidth // force reflow + } + + that.$element + .addClass('in') + .attr('aria-hidden', false) + + that.enforceFocus() + + transition ? + that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown') }) : + that.$element.focus().trigger('shown') + + }) + } + + , hide: function (e) { + e && e.preventDefault() + + var that = this + + e = $.Event('hide') + + this.$element.trigger(e) + + if (!this.isShown || e.isDefaultPrevented()) return + + this.isShown = false + + this.escape() + + $(document).off('focusin.modal') + + this.$element + .removeClass('in') + .attr('aria-hidden', true) + + $.support.transition && this.$element.hasClass('fade') ? + this.hideWithTransition() : + this.hideModal() + } + + , enforceFocus: function () { + var that = this + $(document).on('focusin.modal', function (e) { + if (that.$element[0] !== e.target && !that.$element.has(e.target).length) { + that.$element.focus() + } + }) + } + + , escape: function () { + var that = this + if (this.isShown && this.options.keyboard) { + this.$element.on('keyup.dismiss.modal', function ( e ) { + e.which == 27 && that.hide() + }) + } else if (!this.isShown) { + this.$element.off('keyup.dismiss.modal') + } + } + + , hideWithTransition: function () { + var that = this + , timeout = setTimeout(function () { + that.$element.off($.support.transition.end) + that.hideModal() + }, 500) + + this.$element.one($.support.transition.end, function () { + clearTimeout(timeout) + that.hideModal() + }) + } + + , hideModal: function (that) { + this.$element + .hide() + .trigger('hidden') + + this.backdrop() + } + + , removeBackdrop: function () { + this.$backdrop.remove() + this.$backdrop = null + } + + , backdrop: function (callback) { + var that = this + , animate = this.$element.hasClass('fade') ? 'fade' : '' + + if (this.isShown && this.options.backdrop) { + var doAnimate = $.support.transition && animate + + this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />') + .appendTo(document.body) + + this.$backdrop.click( + this.options.backdrop == 'static' ? + $.proxy(this.$element[0].focus, this.$element[0]) + : $.proxy(this.hide, this) + ) + + if (doAnimate) this.$backdrop[0].offsetWidth // force reflow + + this.$backdrop.addClass('in') + + doAnimate ? + this.$backdrop.one($.support.transition.end, callback) : + callback() + + } else if (!this.isShown && this.$backdrop) { + this.$backdrop.removeClass('in') + + $.support.transition && this.$element.hasClass('fade')? + this.$backdrop.one($.support.transition.end, $.proxy(this.removeBackdrop, this)) : + this.removeBackdrop() + + } else if (callback) { + callback() + } + } + } + + + /* MODAL PLUGIN DEFINITION + * ======================= */ + + $.fn.modal = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('modal') + , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option) + if (!data) $this.data('modal', (data = new Modal(this, options))) + if (typeof option == 'string') data[option]() + else if (options.show) data.show() + }) + } + + $.fn.modal.defaults = { + backdrop: true + , keyboard: true + , show: true + } + + $.fn.modal.Constructor = Modal + + + /* MODAL DATA-API + * ============== */ + + $(document).on('click.modal.data-api', '[data-toggle="modal"]', function (e) { + var $this = $(this) + , href = $this.attr('href') + , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7 + , option = $target.data('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data()) + + e.preventDefault() + + $target + .modal(option) + .one('hide', function () { + $this.focus() + }) + }) + +}(window.jQuery); +/* =========================================================== + * bootstrap-tooltip.js v2.2.1 + * http://twitter.github.com/bootstrap/javascript.html#tooltips + * Inspired by the original jQuery.tipsy by Jason Frame + * =========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* TOOLTIP PUBLIC CLASS DEFINITION + * =============================== */ + + var Tooltip = function (element, options) { + this.init('tooltip', element, options) + } + + Tooltip.prototype = { + + constructor: Tooltip + + , init: function (type, element, options) { + var eventIn + , eventOut + + this.type = type + this.$element = $(element) + this.options = this.getOptions(options) + this.enabled = true + + if (this.options.trigger == 'click') { + this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) + } else if (this.options.trigger != 'manual') { + eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus' + eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur' + this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) + this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) + } + + this.options.selector ? + (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : + this.fixTitle() + } + + , getOptions: function (options) { + options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data()) + + if (options.delay && typeof options.delay == 'number') { + options.delay = { + show: options.delay + , hide: options.delay + } + } + + return options + } + + , enter: function (e) { + var self = $(e.currentTarget)[this.type](this._options).data(this.type) + + if (!self.options.delay || !self.options.delay.show) return self.show() + + clearTimeout(this.timeout) + self.hoverState = 'in' + this.timeout = setTimeout(function() { + if (self.hoverState == 'in') self.show() + }, self.options.delay.show) + } + + , leave: function (e) { + var self = $(e.currentTarget)[this.type](this._options).data(this.type) + + if (this.timeout) clearTimeout(this.timeout) + if (!self.options.delay || !self.options.delay.hide) return self.hide() + + self.hoverState = 'out' + this.timeout = setTimeout(function() { + if (self.hoverState == 'out') self.hide() + }, self.options.delay.hide) + } + + , show: function () { + var $tip + , inside + , pos + , actualWidth + , actualHeight + , placement + , tp + + if (this.hasContent() && this.enabled) { + $tip = this.tip() + this.setContent() + + if (this.options.animation) { + $tip.addClass('fade') + } + + placement = typeof this.options.placement == 'function' ? + this.options.placement.call(this, $tip[0], this.$element[0]) : + this.options.placement + + inside = /in/.test(placement) + + $tip + .detach() + .css({ top: 0, left: 0, display: 'block' }) + .insertAfter(this.$element) + + pos = this.getPosition(inside) + + actualWidth = $tip[0].offsetWidth + actualHeight = $tip[0].offsetHeight + + switch (inside ? placement.split(' ')[1] : placement) { + case 'bottom': + tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2} + break + case 'top': + tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2} + break + case 'left': + tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth} + break + case 'right': + tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width} + break + } + + $tip + .offset(tp) + .addClass(placement) + .addClass('in') + } + } + + , setContent: function () { + var $tip = this.tip() + , title = this.getTitle() + + $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) + $tip.removeClass('fade in top bottom left right') + } + + , hide: function () { + var that = this + , $tip = this.tip() + + $tip.removeClass('in') + + function removeWithAnimation() { + var timeout = setTimeout(function () { + $tip.off($.support.transition.end).detach() + }, 500) + + $tip.one($.support.transition.end, function () { + clearTimeout(timeout) + $tip.detach() + }) + } + + $.support.transition && this.$tip.hasClass('fade') ? + removeWithAnimation() : + $tip.detach() + + return this + } + + , fixTitle: function () { + var $e = this.$element + if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') { + $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title') + } + } + + , hasContent: function () { + return this.getTitle() + } + + , getPosition: function (inside) { + return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), { + width: this.$element[0].offsetWidth + , height: this.$element[0].offsetHeight + }) + } + + , getTitle: function () { + var title + , $e = this.$element + , o = this.options + + title = $e.attr('data-original-title') + || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) + + return title + } + + , tip: function () { + return this.$tip = this.$tip || $(this.options.template) + } + + , validate: function () { + if (!this.$element[0].parentNode) { + this.hide() + this.$element = null + this.options = null + } + } + + , enable: function () { + this.enabled = true + } + + , disable: function () { + this.enabled = false + } + + , toggleEnabled: function () { + this.enabled = !this.enabled + } + + , toggle: function (e) { + var self = $(e.currentTarget)[this.type](this._options).data(this.type) + self[self.tip().hasClass('in') ? 'hide' : 'show']() + } + + , destroy: function () { + this.hide().$element.off('.' + this.type).removeData(this.type) + } + + } + + + /* TOOLTIP PLUGIN DEFINITION + * ========================= */ + + $.fn.tooltip = function ( option ) { + return this.each(function () { + var $this = $(this) + , data = $this.data('tooltip') + , options = typeof option == 'object' && option + if (!data) $this.data('tooltip', (data = new Tooltip(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.tooltip.Constructor = Tooltip + + $.fn.tooltip.defaults = { + animation: true + , placement: 'top' + , selector: false + , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>' + , trigger: 'hover' + , title: '' + , delay: 0 + , html: false + } + +}(window.jQuery);/* =========================================================== + * bootstrap-popover.js v2.2.1 + * http://twitter.github.com/bootstrap/javascript.html#popovers + * =========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* POPOVER PUBLIC CLASS DEFINITION + * =============================== */ + + var Popover = function (element, options) { + this.init('popover', element, options) + } + + + /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js + ========================================== */ + + Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, { + + constructor: Popover + + , setContent: function () { + var $tip = this.tip() + , title = this.getTitle() + , content = this.getContent() + + $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) + $tip.find('.popover-content > *')[this.options.html ? 'html' : 'text'](content) + + $tip.removeClass('fade top bottom left right in') + } + + , hasContent: function () { + return this.getTitle() || this.getContent() + } + + , getContent: function () { + var content + , $e = this.$element + , o = this.options + + content = $e.attr('data-content') + || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content) + + return content + } + + , tip: function () { + if (!this.$tip) { + this.$tip = $(this.options.template) + } + return this.$tip + } + + , destroy: function () { + this.hide().$element.off('.' + this.type).removeData(this.type) + } + + }) + + + /* POPOVER PLUGIN DEFINITION + * ======================= */ + + $.fn.popover = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('popover') + , options = typeof option == 'object' && option + if (!data) $this.data('popover', (data = new Popover(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.popover.Constructor = Popover + + $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, { + placement: 'right' + , trigger: 'click' + , content: '' + , template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>' + }) + +}(window.jQuery);/* ============================================================= + * bootstrap-scrollspy.js v2.2.1 + * http://twitter.github.com/bootstrap/javascript.html#scrollspy + * ============================================================= + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* SCROLLSPY CLASS DEFINITION + * ========================== */ + + function ScrollSpy(element, options) { + var process = $.proxy(this.process, this) + , $element = $(element).is('body') ? $(window) : $(element) + , href + this.options = $.extend({}, $.fn.scrollspy.defaults, options) + this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process) + this.selector = (this.options.target + || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 + || '') + ' .nav li > a' + this.$body = $('body') + this.refresh() + this.process() + } + + ScrollSpy.prototype = { + + constructor: ScrollSpy + + , refresh: function () { + var self = this + , $targets + + this.offsets = $([]) + this.targets = $([]) + + $targets = this.$body + .find(this.selector) + .map(function () { + var $el = $(this) + , href = $el.data('target') || $el.attr('href') + , $href = /^#\w/.test(href) && $(href) + return ( $href + && $href.length + && [[ $href.position().top, href ]] ) || null + }) + .sort(function (a, b) { return a[0] - b[0] }) + .each(function () { + self.offsets.push(this[0]) + self.targets.push(this[1]) + }) + } + + , process: function () { + var scrollTop = this.$scrollElement.scrollTop() + this.options.offset + , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight + , maxScroll = scrollHeight - this.$scrollElement.height() + , offsets = this.offsets + , targets = this.targets + , activeTarget = this.activeTarget + , i + + if (scrollTop >= maxScroll) { + return activeTarget != (i = targets.last()[0]) + && this.activate ( i ) + } + + for (i = offsets.length; i--;) { + activeTarget != targets[i] + && scrollTop >= offsets[i] + && (!offsets[i + 1] || scrollTop <= offsets[i + 1]) + && this.activate( targets[i] ) + } + } + + , activate: function (target) { + var active + , selector + + this.activeTarget = target + + $(this.selector) + .parent('.active') + .removeClass('active') + + selector = this.selector + + '[data-target="' + target + '"],' + + this.selector + '[href="' + target + '"]' + + active = $(selector) + .parent('li') + .addClass('active') + + if (active.parent('.dropdown-menu').length) { + active = active.closest('li.dropdown').addClass('active') + } + + active.trigger('activate') + } + + } + + + /* SCROLLSPY PLUGIN DEFINITION + * =========================== */ + + $.fn.scrollspy = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('scrollspy') + , options = typeof option == 'object' && option + if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.scrollspy.Constructor = ScrollSpy + + $.fn.scrollspy.defaults = { + offset: 10 + } + + + /* SCROLLSPY DATA-API + * ================== */ + + $(window).on('load', function () { + $('[data-spy="scroll"]').each(function () { + var $spy = $(this) + $spy.scrollspy($spy.data()) + }) + }) + +}(window.jQuery);/* ======================================================== + * bootstrap-tab.js v2.2.1 + * http://twitter.github.com/bootstrap/javascript.html#tabs + * ======================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* TAB CLASS DEFINITION + * ==================== */ + + var Tab = function (element) { + this.element = $(element) + } + + Tab.prototype = { + + constructor: Tab + + , show: function () { + var $this = this.element + , $ul = $this.closest('ul:not(.dropdown-menu)') + , selector = $this.attr('data-target') + , previous + , $target + , e + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 + } + + if ( $this.parent('li').hasClass('active') ) return + + previous = $ul.find('.active:last a')[0] + + e = $.Event('show', { + relatedTarget: previous + }) + + $this.trigger(e) + + if (e.isDefaultPrevented()) return + + $target = $(selector) + + this.activate($this.parent('li'), $ul) + this.activate($target, $target.parent(), function () { + $this.trigger({ + type: 'shown' + , relatedTarget: previous + }) + }) + } + + , activate: function ( element, container, callback) { + var $active = container.find('> .active') + , transition = callback + && $.support.transition + && $active.hasClass('fade') + + function next() { + $active + .removeClass('active') + .find('> .dropdown-menu > .active') + .removeClass('active') + + element.addClass('active') + + if (transition) { + element[0].offsetWidth // reflow for transition + element.addClass('in') + } else { + element.removeClass('fade') + } + + if ( element.parent('.dropdown-menu') ) { + element.closest('li.dropdown').addClass('active') + } + + callback && callback() + } + + transition ? + $active.one($.support.transition.end, next) : + next() + + $active.removeClass('in') + } + } + + + /* TAB PLUGIN DEFINITION + * ===================== */ + + $.fn.tab = function ( option ) { + return this.each(function () { + var $this = $(this) + , data = $this.data('tab') + if (!data) $this.data('tab', (data = new Tab(this))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.tab.Constructor = Tab + + + /* TAB DATA-API + * ============ */ + + $(document).on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { + e.preventDefault() + $(this).tab('show') + }) + +}(window.jQuery);/* ============================================================= + * bootstrap-typeahead.js v2.2.1 + * http://twitter.github.com/bootstrap/javascript.html#typeahead + * ============================================================= + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function($){ + + "use strict"; // jshint ;_; + + + /* TYPEAHEAD PUBLIC CLASS DEFINITION + * ================================= */ + + var Typeahead = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, $.fn.typeahead.defaults, options) + 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.$menu = $(this.options.menu).appendTo('body') + this.source = this.options.source + this.shown = false + this.listen() + } + + Typeahead.prototype = { + + constructor: Typeahead + + , select: function () { + var val = this.$menu.find('.active').attr('data-value') + this.$element + .val(this.updater(val)) + .change() + return this.hide() + } + + , updater: function (item) { + return item + } + + , show: function () { + var pos = $.extend({}, this.$element.offset(), { + height: this.$element[0].offsetHeight + }) + + this.$menu.css({ + top: pos.top + pos.height + , left: pos.left + }) + + this.$menu.show() + this.shown = true + return this + } + + , hide: function () { + this.$menu.hide() + this.shown = false + return this + } + + , lookup: function (event) { + var items + + this.query = this.$element.val() + + if (!this.query || this.query.length < this.options.minLength) { + return this.shown ? this.hide() : this + } + + items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source + + return items ? this.process(items) : this + } + + , process: function (items) { + var that = this + + items = $.grep(items, function (item) { + return that.matcher(item) + }) + + items = this.sorter(items) + + if (!items.length) { + return this.shown ? this.hide() : this + } + + return this.render(items.slice(0, this.options.items)).show() + } + + , matcher: function (item) { + return ~item.toLowerCase().indexOf(this.query.toLowerCase()) + } + + , sorter: function (items) { + var beginswith = [] + , caseSensitive = [] + , caseInsensitive = [] + , item + + while (item = items.shift()) { + if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item) + else if (~item.indexOf(this.query)) caseSensitive.push(item) + else caseInsensitive.push(item) + } + + return beginswith.concat(caseSensitive, caseInsensitive) + } + + , highlighter: function (item) { + var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&') + return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) { + return '<strong>' + match + '</strong>' + }) + } + + , render: function (items) { + var that = this + + items = $(items).map(function (i, item) { + i = $(that.options.item).attr('data-value', item) + i.find('a').html(that.highlighter(item)) + return i[0] + }) + + items.first().addClass('active') + this.$menu.html(items) + return this + } + + , next: function (event) { + var active = this.$menu.find('.active').removeClass('active') + , next = active.next() + + if (!next.length) { + next = $(this.$menu.find('li')[0]) + } + + next.addClass('active') + } + + , prev: function (event) { + var active = this.$menu.find('.active').removeClass('active') + , prev = active.prev() + + if (!prev.length) { + prev = this.$menu.find('li').last() + } + + prev.addClass('active') + } + + , listen: function () { + this.$element + .on('blur', $.proxy(this.blur, this)) + .on('keypress', $.proxy(this.keypress, this)) + .on('keyup', $.proxy(this.keyup, this)) + + if (this.eventSupported('keydown')) { + this.$element.on('keydown', $.proxy(this.keydown, this)) + } + + this.$menu + .on('click', $.proxy(this.click, this)) + .on('mouseenter', 'li', $.proxy(this.mouseenter, this)) + } + + , eventSupported: function(eventName) { + var isSupported = eventName in this.$element + if (!isSupported) { + this.$element.setAttribute(eventName, 'return;') + isSupported = typeof this.$element[eventName] === 'function' + } + return isSupported + } + + , move: function (e) { + if (!this.shown) return + + switch(e.keyCode) { + case 9: // tab + case 13: // enter + case 27: // escape + e.preventDefault() + break + + case 38: // up arrow + e.preventDefault() + this.prev() + break + + case 40: // down arrow + e.preventDefault() + this.next() + break + } + + e.stopPropagation() + } + + , keydown: function (e) { + this.suppressKeyPressRepeat = !~$.inArray(e.keyCode, [40,38,9,13,27]) + this.move(e) + } + + , keypress: function (e) { + if (this.suppressKeyPressRepeat) return + this.move(e) + } + + , keyup: function (e) { + switch(e.keyCode) { + case 40: // down arrow + case 38: // up arrow + case 16: // shift + case 17: // ctrl + case 18: // alt + break + + case 9: // tab + case 13: // enter + if (!this.shown) return + this.select() + break + + case 27: // escape + if (!this.shown) return + this.hide() + break + + default: + this.lookup() + } + + e.stopPropagation() + e.preventDefault() + } + + , blur: function (e) { + var that = this + setTimeout(function () { that.hide() }, 150) + } + + , click: function (e) { + e.stopPropagation() + e.preventDefault() + this.select() + } + + , mouseenter: function (e) { + this.$menu.find('.active').removeClass('active') + $(e.currentTarget).addClass('active') + } + + } + + + /* TYPEAHEAD PLUGIN DEFINITION + * =========================== */ + + $.fn.typeahead = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('typeahead') + , options = typeof option == 'object' && option + if (!data) $this.data('typeahead', (data = new Typeahead(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.typeahead.defaults = { + source: [] + , items: 8 + , menu: '<ul class="typeahead dropdown-menu"></ul>' + , item: '<li><a href="#"></a></li>' + , minLength: 1 + } + + $.fn.typeahead.Constructor = Typeahead + + + /* TYPEAHEAD DATA-API + * ================== */ + + $(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) { + var $this = $(this) + if ($this.data('typeahead')) return + e.preventDefault() + $this.typeahead($this.data()) + }) + +}(window.jQuery); +/* ========================================================== + * bootstrap-affix.js v2.2.1 + * http://twitter.github.com/bootstrap/javascript.html#affix + * ========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* AFFIX CLASS DEFINITION + * ====================== */ + + var Affix = function (element, options) { + this.options = $.extend({}, $.fn.affix.defaults, options) + this.$window = $(window) + .on('scroll.affix.data-api', $.proxy(this.checkPosition, this)) + .on('click.affix.data-api', $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this)) + this.$element = $(element) + this.checkPosition() + } + + Affix.prototype.checkPosition = function () { + if (!this.$element.is(':visible')) return + + var scrollHeight = $(document).height() + , scrollTop = this.$window.scrollTop() + , position = this.$element.offset() + , offset = this.options.offset + , offsetBottom = offset.bottom + , offsetTop = offset.top + , reset = 'affix affix-top affix-bottom' + , affix + + if (typeof offset != 'object') offsetBottom = offsetTop = offset + if (typeof offsetTop == 'function') offsetTop = offset.top() + if (typeof offsetBottom == 'function') offsetBottom = offset.bottom() + + affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? + false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? + 'bottom' : offsetTop != null && scrollTop <= offsetTop ? + 'top' : false + + if (this.affixed === affix) return + + this.affixed = affix + this.unpin = affix == 'bottom' ? position.top - scrollTop : null + + this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : '')) + } + + + /* AFFIX PLUGIN DEFINITION + * ======================= */ + + $.fn.affix = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('affix') + , options = typeof option == 'object' && option + if (!data) $this.data('affix', (data = new Affix(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.affix.Constructor = Affix + + $.fn.affix.defaults = { + offset: 0 + } + + + /* AFFIX DATA-API + * ============== */ + + $(window).on('load', function () { + $('[data-spy="affix"]').each(function () { + var $spy = $(this) + , data = $spy.data() + + data.offset = data.offset || {} + + data.offsetBottom && (data.offset.bottom = data.offsetBottom) + data.offsetTop && (data.offset.top = data.offsetTop) + + $spy.affix(data) + }) + }) + + +}(window.jQuery);
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/domReady.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/domReady.js new file mode 100644 index 000000000..6a7977296 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/domReady.js @@ -0,0 +1,125 @@ +/** + * @license RequireJS domReady 2.0.0 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. + * Available via the MIT or new BSD license. + * see: http://github.com/requirejs/domReady for details + */ +/*jslint */ +/*global require: false, define: false, requirejs: false, + window: false, clearInterval: false, document: false, + self: false, setInterval: false */ + + +define(function () { + 'use strict'; + + var isBrowser = typeof window !== "undefined" && window.document, + isPageLoaded = !isBrowser, + doc = isBrowser ? document : null, + readyCalls = [], + isTop, testDiv, scrollIntervalId; + + function runCallbacks(callbacks) { + var i; + for (i = 0; i < callbacks.length; i++) { + callbacks[i](doc); + } + } + + function callReady() { + var callbacks = readyCalls; + + if (isPageLoaded) { + //Call the DOM ready callbacks + if (callbacks.length) { + readyCalls = []; + runCallbacks(callbacks); + } + } + } + + /** + * Sets the page as loaded. + */ + function pageLoaded() { + if (!isPageLoaded) { + isPageLoaded = true; + if (scrollIntervalId) { + clearInterval(scrollIntervalId); + } + + callReady(); + } + } + + if (isBrowser) { + if (document.addEventListener) { + //Standards. Hooray! Assumption here that if standards based, + //it knows about DOMContentLoaded. + document.addEventListener("DOMContentLoaded", pageLoaded, false); + window.addEventListener("load", pageLoaded, false); + } else if (window.attachEvent) { + window.attachEvent("onload", pageLoaded); + + testDiv = document.createElement('div'); + try { + isTop = window.frameElement === null; + } catch(e) {} + + //DOMContentLoaded approximation that uses a doScroll, as found by + //Diego Perini: http://javascript.nwbox.com/IEContentLoaded/, + //but modified by other contributors, including jdalton + if (testDiv.doScroll && isTop && window.external) { + scrollIntervalId = setInterval(function () { + try { + testDiv.doScroll(); + pageLoaded(); + } catch (e) {} + }, 30); + } + } + + //Check if document already complete, and if so, just trigger page load + //listeners. Latest webkit browsers also use "interactive", and + //will fire the onDOMContentLoaded before "interactive" but not after + //entering "interactive" or "complete". More details: + //http://dev.w3.org/html5/spec/the-end.html#the-end + //http://stackoverflow.com/questions/3665561/document-readystate-of-interactive-vs-ondomcontentloaded + if (document.readyState === "complete" || + document.readyState === "interactive") { + pageLoaded(); + } + } + + /** START OF PUBLIC API **/ + + /** + * Registers a callback for DOM ready. If DOM is already ready, the + * callback is called immediately. + * @param {Function} callback + */ + function domReady(callback) { + if (isPageLoaded) { + callback(doc); + } else { + readyCalls.push(callback); + } + return domReady; + } + + domReady.version = '2.0.0'; + + /** + * Loader Plugin API method + */ + domReady.load = function (name, req, onLoad, config) { + if (config.isBuild) { + onLoad(null); + } else { + domReady(onLoad); + } + }; + + /** END OF PUBLIC API **/ + + return domReady; +}); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery-1.8.3.min.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery-1.8.3.min.js new file mode 100644 index 000000000..83589daa7 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery-1.8.3.min.js @@ -0,0 +1,2 @@ +/*! jQuery v1.8.3 jquery.com | jquery.org/license */
+(function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r<i;r++)v.event.add(t,n,u[n][r])}o.data&&(o.data=v.extend({},o.data))}function Ot(e,t){var n;if(t.nodeType!==1)return;t.clearAttributes&&t.clearAttributes(),t.mergeAttributes&&t.mergeAttributes(e),n=t.nodeName.toLowerCase(),n==="object"?(t.parentNode&&(t.outerHTML=e.outerHTML),v.support.html5Clone&&e.innerHTML&&!v.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):n==="input"&&Et.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):n==="option"?t.selected=e.defaultSelected:n==="input"||n==="textarea"?t.defaultValue=e.defaultValue:n==="script"&&t.text!==e.text&&(t.text=e.text),t.removeAttribute(v.expando)}function Mt(e){return typeof e.getElementsByTagName!="undefined"?e.getElementsByTagName("*"):typeof e.querySelectorAll!="undefined"?e.querySelectorAll("*"):[]}function _t(e){Et.test(e.type)&&(e.defaultChecked=e.checked)}function Qt(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Jt.length;while(i--){t=Jt[i]+n;if(t in e)return t}return r}function Gt(e,t){return e=t||e,v.css(e,"display")==="none"||!v.contains(e.ownerDocument,e)}function Yt(e,t){var n,r,i=[],s=0,o=e.length;for(;s<o;s++){n=e[s];if(!n.style)continue;i[s]=v._data(n,"olddisplay"),t?(!i[s]&&n.style.display==="none"&&(n.style.display=""),n.style.display===""&&Gt(n)&&(i[s]=v._data(n,"olddisplay",nn(n.nodeName)))):(r=Dt(n,"display"),!i[s]&&r!=="none"&&v._data(n,"olddisplay",r))}for(s=0;s<o;s++){n=e[s];if(!n.style)continue;if(!t||n.style.display==="none"||n.style.display==="")n.style.display=t?i[s]||"":"none"}return e}function Zt(e,t,n){var r=Rt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function en(e,t,n,r){var i=n===(r?"border":"content")?4:t==="width"?1:0,s=0;for(;i<4;i+=2)n==="margin"&&(s+=v.css(e,n+$t[i],!0)),r?(n==="content"&&(s-=parseFloat(Dt(e,"padding"+$t[i]))||0),n!=="margin"&&(s-=parseFloat(Dt(e,"border"+$t[i]+"Width"))||0)):(s+=parseFloat(Dt(e,"padding"+$t[i]))||0,n!=="padding"&&(s+=parseFloat(Dt(e,"border"+$t[i]+"Width"))||0));return s}function tn(e,t,n){var r=t==="width"?e.offsetWidth:e.offsetHeight,i=!0,s=v.support.boxSizing&&v.css(e,"boxSizing")==="border-box";if(r<=0||r==null){r=Dt(e,t);if(r<0||r==null)r=e.style[t];if(Ut.test(r))return r;i=s&&(v.support.boxSizingReliable||r===e.style[t]),r=parseFloat(r)||0}return r+en(e,t,n||(s?"border":"content"),i)+"px"}function nn(e){if(Wt[e])return Wt[e];var t=v("<"+e+">").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write("<!doctype html><html><body>"),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u<a;u++)r=o[u],s=/^\+/.test(r),s&&(r=r.substr(1)||"*"),i=e[r]=e[r]||[],i[s?"unshift":"push"](n)}}function kn(e,n,r,i,s,o){s=s||n.dataTypes[0],o=o||{},o[s]=!0;var u,a=e[s],f=0,l=a?a.length:0,c=e===Sn;for(;f<l&&(c||!u);f++)u=a[f](n,r,i),typeof u=="string"&&(!c||o[u]?u=t:(n.dataTypes.unshift(u),u=kn(e,n,r,i,u,o)));return(c||!u)&&!o["*"]&&(u=kn(e,n,r,i,"*",o)),u}function Ln(e,n){var r,i,s=v.ajaxSettings.flatOptions||{};for(r in n)n[r]!==t&&((s[r]?e:i||(i={}))[r]=n[r]);i&&v.extend(!0,e,i)}function An(e,n,r){var i,s,o,u,a=e.contents,f=e.dataTypes,l=e.responseFields;for(s in l)s in r&&(n[l[s]]=r[s]);while(f[0]==="*")f.shift(),i===t&&(i=e.mimeType||n.getResponseHeader("content-type"));if(i)for(s in a)if(a[s]&&a[s].test(i)){f.unshift(s);break}if(f[0]in r)o=f[0];else{for(s in r){if(!f[0]||e.converters[s+" "+f[0]]){o=s;break}u||(u=s)}o=o||u}if(o)return o!==f[0]&&f.unshift(o),r[o]}function On(e,t){var n,r,i,s,o=e.dataTypes.slice(),u=o[0],a={},f=0;e.dataFilter&&(t=e.dataFilter(t,e.dataType));if(o[1])for(n in e.converters)a[n.toLowerCase()]=e.converters[n];for(;i=o[++f];)if(i!=="*"){if(u!=="*"&&u!==i){n=a[u+" "+i]||a["* "+i];if(!n)for(r in a){s=r.split(" ");if(s[1]===i){n=a[u+" "+s[0]]||a["* "+s[0]];if(n){n===!0?n=a[r]:a[r]!==!0&&(i=s[0],o.splice(f--,0,i));break}}}if(n!==!0)if(n&&e["throws"])t=n(t);else try{t=n(t)}catch(l){return{state:"parsererror",error:n?l:"No conversion from "+u+" to "+i}}}u=i}return{state:"success",data:t}}function Fn(){try{return new e.XMLHttpRequest}catch(t){}}function In(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}function $n(){return setTimeout(function(){qn=t},0),qn=v.now()}function Jn(e,t){v.each(t,function(t,n){var r=(Vn[t]||[]).concat(Vn["*"]),i=0,s=r.length;for(;i<s;i++)if(r[i].call(e,t,n))return})}function Kn(e,t,n){var r,i=0,s=0,o=Xn.length,u=v.Deferred().always(function(){delete a.elem}),a=function(){var t=qn||$n(),n=Math.max(0,f.startTime+f.duration-t),r=n/f.duration||0,i=1-r,s=0,o=f.tweens.length;for(;s<o;s++)f.tweens[s].run(i);return u.notifyWith(e,[f,i,n]),i<1&&o?n:(u.resolveWith(e,[f]),!1)},f=u.promise({elem:e,props:v.extend({},t),opts:v.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:qn||$n(),duration:n.duration,tweens:[],createTween:function(t,n,r){var i=v.Tween(e,f.opts,t,n,f.opts.specialEasing[t]||f.opts.easing);return f.tweens.push(i),i},stop:function(t){var n=0,r=t?f.tweens.length:0;for(;n<r;n++)f.tweens[n].run(1);return t?u.resolveWith(e,[f,t]):u.rejectWith(e,[f,t]),this}}),l=f.props;Qn(l,f.opts.specialEasing);for(;i<o;i++){r=Xn[i].call(f,e,l,f.opts);if(r)return r}return Jn(f,l),v.isFunction(f.opts.start)&&f.opts.start.call(e,f),v.fx.timer(v.extend(a,{anim:f,queue:f.opts.queue,elem:e})),f.progress(f.opts.progress).done(f.opts.done,f.opts.complete).fail(f.opts.fail).always(f.opts.always)}function Qn(e,t){var n,r,i,s,o;for(n in e){r=v.camelCase(n),i=t[r],s=e[n],v.isArray(s)&&(i=s[1],s=e[n]=s[0]),n!==r&&(e[r]=s,delete e[n]),o=v.cssHooks[r];if(o&&"expand"in o){s=o.expand(s),delete e[r];for(n in s)n in e||(e[n]=s[n],t[n]=i)}else t[r]=i}}function Gn(e,t,n){var r,i,s,o,u,a,f,l,c,h=this,p=e.style,d={},m=[],g=e.nodeType&&Gt(e);n.queue||(l=v._queueHooks(e,"fx"),l.unqueued==null&&(l.unqueued=0,c=l.empty.fire,l.empty.fire=function(){l.unqueued||c()}),l.unqueued++,h.always(function(){h.always(function(){l.unqueued--,v.queue(e,"fx").length||l.empty.fire()})})),e.nodeType===1&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],v.css(e,"display")==="inline"&&v.css(e,"float")==="none"&&(!v.support.inlineBlockNeedsLayout||nn(e.nodeName)==="inline"?p.display="inline-block":p.zoom=1)),n.overflow&&(p.overflow="hidden",v.support.shrinkWrapBlocks||h.done(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t){s=t[r];if(Un.exec(s)){delete t[r],a=a||s==="toggle";if(s===(g?"hide":"show"))continue;m.push(r)}}o=m.length;if(o){u=v._data(e,"fxshow")||v._data(e,"fxshow",{}),"hidden"in u&&(g=u.hidden),a&&(u.hidden=!g),g?v(e).show():h.done(function(){v(e).hide()}),h.done(function(){var t;v.removeData(e,"fxshow",!0);for(t in d)v.style(e,t,d[t])});for(r=0;r<o;r++)i=m[r],f=h.createTween(i,g?u[i]:0),d[i]=u[i]||v.style(e,i),i in u||(u[i]=f.start,g&&(f.end=f.start,f.start=i==="width"||i==="height"?1:0))}}function Yn(e,t,n,r,i){return new Yn.prototype.init(e,t,n,r,i)}function Zn(e,t){var n,r={height:e},i=0;t=t?1:0;for(;i<4;i+=2-t)n=$t[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}function tr(e){return v.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:!1}var n,r,i=e.document,s=e.location,o=e.navigator,u=e.jQuery,a=e.$,f=Array.prototype.push,l=Array.prototype.slice,c=Array.prototype.indexOf,h=Object.prototype.toString,p=Object.prototype.hasOwnProperty,d=String.prototype.trim,v=function(e,t){return new v.fn.init(e,t,n)},m=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,g=/\S/,y=/\s+/,b=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,w=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a<f;a++)if((e=arguments[a])!=null)for(n in e){r=u[n],i=e[n];if(u===i)continue;l&&i&&(v.isPlainObject(i)||(s=v.isArray(i)))?(s?(s=!1,o=r&&v.isArray(r)?r:[]):o=r&&v.isPlainObject(r)?r:{},u[n]=v.extend(l,o,i)):i!==t&&(u[n]=i)}return u},v.extend({noConflict:function(t){return e.$===v&&(e.$=a),t&&e.jQuery===v&&(e.jQuery=u),v},isReady:!1,readyWait:1,holdReady:function(e){e?v.readyWait++:v.ready(!0)},ready:function(e){if(e===!0?--v.readyWait:v.isReady)return;if(!i.body)return setTimeout(v.ready,1);v.isReady=!0;if(e!==!0&&--v.readyWait>0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s<o;)if(n.apply(e[s++],r)===!1)break}else if(u){for(i in e)if(n.call(e[i],i,e[i])===!1)break}else for(;s<o;)if(n.call(e[s],s,e[s++])===!1)break;return e},trim:d&&!d.call("\ufeff\u00a0")?function(e){return e==null?"":d.call(e)}:function(e){return e==null?"":(e+"").replace(b,"")},makeArray:function(e,t){var n,r=t||[];return e!=null&&(n=v.type(e),e.length==null||n==="string"||n==="function"||n==="regexp"||v.isWindow(e)?f.call(r,e):v.merge(r,e)),r},inArray:function(e,t,n){var r;if(t){if(c)return c.call(t,e,n);r=t.length,n=n?n<0?Math.max(0,r+n):n:0;for(;n<r;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,s=0;if(typeof r=="number")for(;s<r;s++)e[i++]=n[s];else while(n[s]!==t)e[i++]=n[s++];return e.length=i,e},grep:function(e,t,n){var r,i=[],s=0,o=e.length;n=!!n;for(;s<o;s++)r=!!t(e[s],s),n!==r&&i.push(e[s]);return i},map:function(e,n,r){var i,s,o=[],u=0,a=e.length,f=e instanceof v||a!==t&&typeof a=="number"&&(a>0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u<a;u++)i=n(e[u],u,r),i!=null&&(o[o.length]=i);else for(s in e)i=n(e[s],s,r),i!=null&&(o[o.length]=i);return o.concat.apply([],o)},guid:1,proxy:function(e,n){var r,i,s;return typeof n=="string"&&(r=e[n],n=e,e=r),v.isFunction(e)?(i=l.call(arguments,2),s=function(){return e.apply(n,i.concat(l.call(arguments)))},s.guid=e.guid=e.guid||v.guid++,s):t},access:function(e,n,r,i,s,o,u){var a,f=r==null,l=0,c=e.length;if(r&&typeof r=="object"){for(l in r)v.access(e,n,l,r[l],1,o,i);s=1}else if(i!==t){a=u===t&&v.isFunction(i),f&&(a?(a=n,n=function(e,t,n){return a.call(v(e),n)}):(n.call(e,i),n=null));if(n)for(;l<c;l++)n(e[l],r,a?i.call(e[l],l,n(e[l],r)):i,u);s=1}return s?e:f?n.call(e):c?n(e[0],r):o},now:function(){return(new Date).getTime()}}),v.ready.promise=function(t){if(!r){r=v.Deferred();if(i.readyState==="complete")setTimeout(v.ready,1);else if(i.addEventListener)i.addEventListener("DOMContentLoaded",A,!1),e.addEventListener("load",v.ready,!1);else{i.attachEvent("onreadystatechange",A),e.attachEvent("onload",v.ready);var n=!1;try{n=e.frameElement==null&&i.documentElement}catch(s){}n&&n.doScroll&&function o(){if(!v.isReady){try{n.doScroll("left")}catch(e){return setTimeout(o,50)}v.ready()}}()}}return r.promise(t)},v.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(e,t){O["[object "+t+"]"]=t.toLowerCase()}),n=v(i);var M={};v.Callbacks=function(e){e=typeof e=="string"?M[e]||_(e):v.extend({},e);var n,r,i,s,o,u,a=[],f=!e.once&&[],l=function(t){n=e.memory&&t,r=!0,u=s||0,s=0,o=a.length,i=!0;for(;a&&u<o;u++)if(a[u].apply(t[0],t[1])===!1&&e.stopOnFalse){n=!1;break}i=!1,a&&(f?f.length&&l(f.shift()):n?a=[]:c.disable())},c={add:function(){if(a){var t=a.length;(function r(t){v.each(t,function(t,n){var i=v.type(n);i==="function"?(!e.unique||!c.has(n))&&a.push(n):n&&n.length&&i!=="string"&&r(n)})})(arguments),i?o=a.length:n&&(s=t,l(n))}return this},remove:function(){return a&&v.each(arguments,function(e,t){var n;while((n=v.inArray(t,a,n))>-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t<r;t++)n[t]&&v.isFunction(n[t].promise)?n[t].promise().done(o(t,f,n)).fail(s.reject).progress(o(t,a,u)):--i}return i||s.resolveWith(f,n),s.promise()}}),v.support=function(){var t,n,r,s,o,u,a,f,l,c,h,p=i.createElement("div");p.setAttribute("className","t"),p.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="<table><tr><td></td><td>t</td></tr></table>",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="<div></div>",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i<s;i++)delete r[t[i]];if(!(n?B:v.isEmptyObject)(r))return}}if(!n){delete u[a].data;if(!B(u[a]))return}o?v.cleanData([e],!0):v.support.deleteExpando||u!=u.window?delete u[a]:u[a]=null},_data:function(e,t,n){return v.data(e,t,n,!0)},acceptData:function(e){var t=e.nodeName&&v.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),v.fn.extend({data:function(e,n){var r,i,s,o,u,a=this[0],f=0,l=null;if(e===t){if(this.length){l=v.data(a);if(a.nodeType===1&&!v._data(a,"parsedAttrs")){s=a.attributes;for(u=s.length;f<u;f++)o=s[f].name,o.indexOf("data-")||(o=v.camelCase(o.substring(5)),H(a,o,l[o]));v._data(a,"parsedAttrs",!0)}}return l}return typeof e=="object"?this.each(function(){v.data(this,e)}):(r=e.split(".",2),r[1]=r[1]?"."+r[1]:"",i=r[1]+"!",v.access(this,function(n){if(n===t)return l=this.triggerHandler("getData"+i,[r[0]]),l===t&&a&&(l=v.data(a,e),l=H(a,e,l)),l===t&&r[1]?this.data(r[0]):l;r[1]=n,this.each(function(){var t=v(this);t.triggerHandler("setData"+i,r),v.data(this,e,n),t.triggerHandler("changeData"+i,r)})},null,n,arguments.length>1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length<r?v.queue(this[0],e):n===t?this:this.each(function(){var t=v.queue(this,e,n);v._queueHooks(this,e),e==="fx"&&t[0]!=="inprogress"&&v.dequeue(this,e)})},dequeue:function(e){return this.each(function(){v.dequeue(this,e)})},delay:function(e,t){return e=v.fx?v.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,s=v.Deferred(),o=this,u=this.length,a=function(){--i||s.resolveWith(o,[o])};typeof e!="string"&&(n=e,e=t),e=e||"fx";while(u--)r=v._data(o[u],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(a));return a(),s.promise(n)}});var j,F,I,q=/[\t\r\n]/g,R=/\r/g,U=/^(?:button|input)$/i,z=/^(?:button|input|object|select|textarea)$/i,W=/^a(?:rea|)$/i,X=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,V=v.support.getSetAttribute;v.fn.extend({attr:function(e,t){return v.access(this,v.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n<r;n++){i=this[n];if(i.nodeType===1)if(!i.className&&t.length===1)i.className=e;else{s=" "+i.className+" ";for(o=0,u=t.length;o<u;o++)s.indexOf(" "+t[o]+" ")<0&&(s+=t[o]+" ");i.className=v.trim(s)}}}return this},removeClass:function(e){var n,r,i,s,o,u,a;if(v.isFunction(e))return this.each(function(t){v(this).removeClass(e.call(this,t,this.className))});if(e&&typeof e=="string"||e===t){n=(e||"").split(y);for(u=0,a=this.length;u<a;u++){i=this[u];if(i.nodeType===1&&i.className){r=(" "+i.className+" ").replace(q," ");for(s=0,o=n.length;s<o;s++)while(r.indexOf(" "+n[s]+" ")>=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n<r;n++)if(this[n].nodeType===1&&(" "+this[n].className+" ").replace(q," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a<u;a++){n=r[a];if((n.selected||a===i)&&(v.support.optDisabled?!n.disabled:n.getAttribute("disabled")===null)&&(!n.parentNode.disabled||!v.nodeName(n.parentNode,"optgroup"))){t=v(n).val();if(s)return t;o.push(t)}}return o},set:function(e,t){var n=v.makeArray(t);return v(e).find("option").each(function(){this.selected=v.inArray(v(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o<r.length;o++)i=r[o],i&&(n=v.propFix[i]||i,s=X.test(i),s||v.attr(e,i,""),e.removeAttribute(V?i:n),s&&n in e&&(e[n]=!1))}},attrHooks:{type:{set:function(e,t){if(U.test(e.nodeName)&&e.parentNode)v.error("type property can't be changed");else if(!v.support.radioValue&&t==="radio"&&v.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}},value:{get:function(e,t){return j&&v.nodeName(e,"button")?j.get(e,t):t in e?e.value:null},set:function(e,t,n){if(j&&v.nodeName(e,"button"))return j.set(e,t,n);e.value=t}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,s,o,u=e.nodeType;if(!e||u===3||u===8||u===2)return;return o=u!==1||!v.isXMLDoc(e),o&&(n=v.propFix[n]||n,s=v.propHooks[n]),r!==t?s&&"set"in s&&(i=s.set(e,r,n))!==t?i:e[n]=r:s&&"get"in s&&(i=s.get(e,n))!==null?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):z.test(e.nodeName)||W.test(e.nodeName)&&e.href?0:t}}}}),F={get:function(e,n){var r,i=v.prop(e,n);return i===!0||typeof i!="boolean"&&(r=e.getAttributeNode(n))&&r.nodeValue!==!1?n.toLowerCase():t},set:function(e,t,n){var r;return t===!1?v.removeAttr(e,n):(r=v.propFix[n]||n,r in e&&(e[r]=!0),e.setAttribute(n,n.toLowerCase())),n}},V||(I={name:!0,id:!0,coords:!0},j=v.valHooks.button={get:function(e,n){var r;return r=e.getAttributeNode(n),r&&(I[n]?r.value!=="":r.specified)?r.value:t},set:function(e,t,n){var r=e.getAttributeNode(n);return r||(r=i.createAttribute(n),e.setAttributeNode(r)),r.value=t+""}},v.each(["width","height"],function(e,t){v.attrHooks[t]=v.extend(v.attrHooks[t],{set:function(e,n){if(n==="")return e.setAttribute(t,"auto"),n}})}),v.attrHooks.contenteditable={get:j.get,set:function(e,t,n){t===""&&(t="false"),j.set(e,t,n)}}),v.support.hrefNormalized||v.each(["href","src","width","height"],function(e,n){v.attrHooks[n]=v.extend(v.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return r===null?t:r}})}),v.support.style||(v.attrHooks.style={get:function(e){return e.style.cssText.toLowerCase()||t},set:function(e,t){return e.style.cssText=t+""}}),v.support.optSelected||(v.propHooks.selected=v.extend(v.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),v.support.enctype||(v.propFix.enctype="encoding"),v.support.checkOn||v.each(["radio","checkbox"],function(){v.valHooks[this]={get:function(e){return e.getAttribute("value")===null?"on":e.value}}}),v.each(["radio","checkbox"],function(){v.valHooks[this]=v.extend(v.valHooks[this],{set:function(e,t){if(v.isArray(t))return e.checked=v.inArray(v(e).val(),t)>=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f<n.length;f++){l=J.exec(n[f])||[],c=l[1],h=(l[2]||"").split(".").sort(),g=v.event.special[c]||{},c=(s?g.delegateType:g.bindType)||c,g=v.event.special[c]||{},p=v.extend({type:c,origType:l[1],data:i,handler:r,guid:r.guid,selector:s,needsContext:s&&v.expr.match.needsContext.test(s),namespace:h.join(".")},d),m=a[c];if(!m){m=a[c]=[],m.delegateCount=0;if(!g.setup||g.setup.call(e,i,h,u)===!1)e.addEventListener?e.addEventListener(c,u,!1):e.attachEvent&&e.attachEvent("on"+c,u)}g.add&&(g.add.call(e,p),p.handler.guid||(p.handler.guid=r.guid)),s?m.splice(m.delegateCount++,0,p):m.push(p),v.event.global[c]=!0}e=null},global:{},remove:function(e,t,n,r,i){var s,o,u,a,f,l,c,h,p,d,m,g=v.hasData(e)&&v._data(e);if(!g||!(h=g.events))return;t=v.trim(Z(t||"")).split(" ");for(s=0;s<t.length;s++){o=J.exec(t[s])||[],u=a=o[1],f=o[2];if(!u){for(u in h)v.event.remove(e,u+t[s],n,r,!0);continue}p=v.event.special[u]||{},u=(r?p.delegateType:p.bindType)||u,d=h[u]||[],l=d.length,f=f?new RegExp("(^|\\.)"+f.split(".").sort().join("\\.(?:.*\\.|)")+"(\\.|$)"):null;for(c=0;c<d.length;c++)m=d[c],(i||a===m.origType)&&(!n||n.guid===m.guid)&&(!f||f.test(m.namespace))&&(!r||r===m.selector||r==="**"&&m.selector)&&(d.splice(c--,1),m.selector&&d.delegateCount--,p.remove&&p.remove.call(e,m));d.length===0&&l!==d.length&&((!p.teardown||p.teardown.call(e,f,g.handle)===!1)&&v.removeEvent(e,u,g.handle),delete h[u])}v.isEmptyObject(h)&&(delete g.handle,v.removeData(e,"events",!0))},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(n,r,s,o){if(!s||s.nodeType!==3&&s.nodeType!==8){var u,a,f,l,c,h,p,d,m,g,y=n.type||n,b=[];if(Y.test(y+v.event.triggered))return;y.indexOf("!")>=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f<m.length&&!n.isPropagationStopped();f++)l=m[f][0],n.type=m[f][1],d=(v._data(l,"events")||{})[n.type]&&v._data(l,"handle"),d&&d.apply(l,r),d=h&&l[h],d&&v.acceptData(l)&&d.apply&&d.apply(l,r)===!1&&n.preventDefault();return n.type=y,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(s.ownerDocument,r)===!1)&&(y!=="click"||!v.nodeName(s,"a"))&&v.acceptData(s)&&h&&s[y]&&(y!=="focus"&&y!=="blur"||n.target.offsetWidth!==0)&&!v.isWindow(s)&&(c=s[h],c&&(s[h]=null),v.event.triggered=y,s[y](),v.event.triggered=t,c&&(s[h]=c)),n.result}return},dispatch:function(n){n=v.event.fix(n||e.event);var r,i,s,o,u,a,f,c,h,p,d=(v._data(this,"events")||{})[n.type]||[],m=d.delegateCount,g=l.call(arguments),y=!n.exclusive&&!n.namespace,b=v.event.special[n.type]||{},w=[];g[0]=n,n.delegateTarget=this;if(b.preDispatch&&b.preDispatch.call(this,n)===!1)return;if(m&&(!n.button||n.type!=="click"))for(s=n.target;s!=this;s=s.parentNode||this)if(s.disabled!==!0||n.type!=="click"){u={},f=[];for(r=0;r<m;r++)c=d[r],h=c.selector,u[h]===t&&(u[h]=c.needsContext?v(h,this).index(s)>=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r<w.length&&!n.isPropagationStopped();r++){a=w[r],n.currentTarget=a.elem;for(i=0;i<a.matches.length&&!n.isImmediatePropagationStopped();i++){c=a.matches[i];if(y||!n.namespace&&!c.namespace||n.namespace_re&&n.namespace_re.test(c.namespace))n.data=c.data,n.handleObj=c,o=((v.event.special[c.origType]||{}).handle||c.handler).apply(a.elem,g),o!==t&&(n.result=o,o===!1&&(n.preventDefault(),n.stopPropagation()))}}return b.postDispatch&&b.postDispatch.call(this,n),n.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return e.which==null&&(e.which=t.charCode!=null?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,s,o,u=n.button,a=n.fromElement;return e.pageX==null&&n.clientX!=null&&(r=e.target.ownerDocument||i,s=r.documentElement,o=r.body,e.pageX=n.clientX+(s&&s.scrollLeft||o&&o.scrollLeft||0)-(s&&s.clientLeft||o&&o.clientLeft||0),e.pageY=n.clientY+(s&&s.scrollTop||o&&o.scrollTop||0)-(s&&s.clientTop||o&&o.clientTop||0)),!e.relatedTarget&&a&&(e.relatedTarget=a===e.target?n.toElement:a),!e.which&&u!==t&&(e.which=u&1?1:u&2?3:u&4?2:0),e}},fix:function(e){if(e[v.expando])return e;var t,n,r=e,s=v.event.fixHooks[e.type]||{},o=s.props?this.props.concat(s.props):this.props;e=v.Event(r);for(t=o.length;t;)n=o[--t],e[n]=r[n];return e.target||(e.target=r.srcElement||i),e.target.nodeType===3&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,r):e},special:{load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(e,t,n){v.isWindow(this)&&(this.onbeforeunload=n)},teardown:function(e,t){this.onbeforeunload===t&&(this.onbeforeunload=null)}}},simulate:function(e,t,n,r){var i=v.extend(new v.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?v.event.trigger(i,null,t):v.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},v.event.handle=v.event.dispatch,v.removeEvent=i.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]=="undefined"&&(e[r]=null),e.detachEvent(r,n))},v.Event=function(e,t){if(!(this instanceof v.Event))return new v.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?tt:et):this.type=e,t&&v.extend(this,t),this.timeStamp=e&&e.timeStamp||v.now(),this[v.expando]=!0},v.Event.prototype={preventDefault:function(){this.isDefaultPrevented=tt;var e=this.originalEvent;if(!e)return;e.preventDefault?e.preventDefault():e.returnValue=!1},stopPropagation:function(){this.isPropagationStopped=tt;var e=this.originalEvent;if(!e)return;e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=tt,this.stopPropagation()},isDefaultPrevented:et,isPropagationStopped:et,isImmediatePropagationStopped:et},v.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){v.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,s=e.handleObj,o=s.selector;if(!i||i!==r&&!v.contains(r,i))e.type=s.origType,n=s.handler.apply(this,arguments),e.type=t;return n}}}),v.support.submitBubbles||(v.event.special.submit={setup:function(){if(v.nodeName(this,"form"))return!1;v.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=v.nodeName(n,"input")||v.nodeName(n,"button")?n.form:t;r&&!v._data(r,"_submit_attached")&&(v.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),v._data(r,"_submit_attached",!0))})},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&v.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){if(v.nodeName(this,"form"))return!1;v.event.remove(this,"._submit")}}),v.support.changeBubbles||(v.event.special.change={setup:function(){if($.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")v.event.add(this,"propertychange._change",function(e){e.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),v.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),v.event.simulate("change",this,e,!0)});return!1}v.event.add(this,"beforeactivate._change",function(e){var t=e.target;$.test(t.nodeName)&&!v._data(t,"_change_attached")&&(v.event.add(t,"change._change",function(e){this.parentNode&&!e.isSimulated&&!e.isTrigger&&v.event.simulate("change",this.parentNode,e,!0)}),v._data(t,"_change_attached",!0))})},handle:function(e){var t=e.target;if(this!==t||e.isSimulated||e.isTrigger||t.type!=="radio"&&t.type!=="checkbox")return e.handleObj.handler.apply(this,arguments)},teardown:function(){return v.event.remove(this,"._change"),!$.test(this.nodeName)}}),v.support.focusinBubbles||v.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){v.event.simulate(t,e.target,v.event.fix(e),!0)};v.event.special[t]={setup:function(){n++===0&&i.addEventListener(e,r,!0)},teardown:function(){--n===0&&i.removeEventListener(e,r,!0)}}}),v.fn.extend({on:function(e,n,r,i,s){var o,u;if(typeof e=="object"){typeof n!="string"&&(r=r||n,n=t);for(u in e)this.on(u,n,r,e[u],s);return this}r==null&&i==null?(i=n,r=n=t):i==null&&(typeof n=="string"?(i=r,r=t):(i=r,r=n,n=t));if(i===!1)i=et;else if(!i)return this;return s===1&&(o=i,i=function(e){return v().off(e),o.apply(this,arguments)},i.guid=o.guid||(o.guid=v.guid++)),this.each(function(){v.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,s;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,v(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if(typeof e=="object"){for(s in e)this.off(s,n,e[s]);return this}if(n===!1||typeof n=="function")r=n,n=t;return r===!1&&(r=et),this.each(function(){v.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},live:function(e,t,n){return v(this.context).on(e,this.selector,t,n),this},die:function(e,t){return v(this.context).off(e,this.selector||"**",t),this},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return arguments.length===1?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){v.event.trigger(e,t,this)})},triggerHandler:function(e,t){if(this[0])return v.event.trigger(e,t,this[0],!0)},toggle:function(e){var t=arguments,n=e.guid||v.guid++,r=0,i=function(n){var i=(v._data(this,"lastToggle"+e.guid)||0)%r;return v._data(this,"lastToggle"+e.guid,i+1),n.preventDefault(),t[i].apply(this,arguments)||!1};i.guid=n;while(r<t.length)t[r++].guid=n;return this.click(i)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),v.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){v.fn[t]=function(e,n){return n==null&&(n=e,e=null),arguments.length>0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u<a;u++)if(s=e[u])if(!n||n(s,r,i))o.push(s),f&&t.push(u);return o}function ct(e,t,n,r,i,s){return r&&!r[d]&&(r=ct(r)),i&&!i[d]&&(i=ct(i,s)),N(function(s,o,u,a){var f,l,c,h=[],p=[],d=o.length,v=s||dt(t||"*",u.nodeType?[u]:u,[]),m=e&&(s||!t)?lt(v,h,e,u,a):v,g=n?i||(s?e:d||r)?[]:o:m;n&&n(m,g,u,a);if(r){f=lt(g,p),r(f,[],u,a),l=f.length;while(l--)if(c=f[l])g[p[l]]=!(m[p[l]]=c)}if(s){if(i||e){if(i){f=[],l=g.length;while(l--)(c=g[l])&&f.push(m[l]=c);i(null,g=[],f,a)}l=g.length;while(l--)(c=g[l])&&(f=i?T.call(s,c):h[l])>-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a<s;a++)if(n=i.relative[e[a].type])h=[at(ft(h),n)];else{n=i.filter[e[a].type].apply(null,e[a].matches);if(n[d]){r=++a;for(;r<s;r++)if(i.relative[e[r].type])break;return ct(a>1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a<r&&ht(e.slice(a,r)),r<s&&ht(e=e.slice(r)),r<s&&e.join(""))}h.push(n)}return ft(h)}function pt(e,t){var r=t.length>0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r<i;r++)nt(e,t[r],n);return n}function vt(e,t,n,r,s){var o,u,f,l,c,h=ut(e),p=h.length;if(!r&&h.length===1){u=h[0]=h[0].slice(0);if(u.length>2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;t<n;t++)if(this[t]===e)return t;return-1},N=function(e,t){return e[d]=t==null||t,e},C=function(){var e={},t=[];return N(function(n,r){return t.push(n)>i.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="<a href='#'></a>",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="<select></select>";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="<a name='"+d+"'></a><div name='"+d+"'></div>",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:st(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:st(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},f=y.compareDocumentPosition?function(e,t){return e===t?(l=!0,0):(!e.compareDocumentPosition||!t.compareDocumentPosition?e.compareDocumentPosition:e.compareDocumentPosition(t)&4)?-1:1}:function(e,t){if(e===t)return l=!0,0;if(e.sourceIndex&&t.sourceIndex)return e.sourceIndex-t.sourceIndex;var n,r,i=[],s=[],o=e.parentNode,u=t.parentNode,a=o;if(o===u)return ot(e,t);if(!o)return-1;if(!u)return 1;while(a)i.unshift(a),a=a.parentNode;a=u;while(a)s.unshift(a),a=a.parentNode;n=i.length,r=s.length;for(var f=0;f<n&&f<r;f++)if(i[f]!==s[f])return ot(i[f],s[f]);return f===n?ot(e,s[f],-1):ot(i[f],t,1)},[0,0].sort(f),h=!l,nt.uniqueSort=function(e){var t,n=[],r=1,i=0;l=h,e.sort(f);if(l){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e},nt.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},a=nt.compile=function(e,t){var n,r=[],i=[],s=A[d][e+" "];if(!s){t||(t=ut(e)),n=t.length;while(n--)s=ht(t[n]),s[d]?r.push(s):i.push(s);s=A(e,pt(i,r))}return s},g.querySelectorAll&&function(){var e,t=vt,n=/'|\\/g,r=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,i=[":focus"],s=[":active"],u=y.matchesSelector||y.mozMatchesSelector||y.webkitMatchesSelector||y.oMatchesSelector||y.msMatchesSelector;K(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="<p test=''></p>",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="<input type='hidden'/>",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t<n;t++)if(v.contains(u[t],this))return!0});o=this.pushStack("","find",e);for(t=0,n=this.length;t<n;t++){r=o.length,v.find(e,this[t],o);if(t>0)for(i=r;i<o.length;i++)for(s=0;s<r;s++)if(o[s]===o[i]){o.splice(i--,1);break}}return o},has:function(e){var t,n=v(e,this),r=n.length;return this.filter(function(){for(t=0;t<r;t++)if(v.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1),"not",e)},filter:function(e){return this.pushStack(ft(this,e,!0),"filter",e)},is:function(e){return!!e&&(typeof e=="string"?st.test(e)?v(e,this.context).index(this[0])>=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r<i;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&n.nodeType!==11){if(o?o.index(n)>-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/<tbody/i,gt=/<|&#?\w+;/,yt=/<(?:script|style|link)/i,bt=/<(?:script|object|embed|option|style)/i,wt=new RegExp("<(?:"+ct+")[\\s/>]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,Nt={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X<div>","</div>"]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1></$2>");try{for(;r<i;r++)n=this[r]||{},n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),n.innerHTML=e);n=0}catch(s){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){return ut(this[0])?this.length?this.pushStack(v(v.isFunction(e)?e():e),"replaceWith",e):this:v.isFunction(e)?this.each(function(t){var n=v(this),r=n.html();n.replaceWith(e.call(this,t,r))}):(typeof e!="string"&&(e=v(e).detach()),this.each(function(){var t=this.nextSibling,n=this.parentNode;v(this).remove(),t?v(t).before(e):v(n).append(e)}))},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=[].concat.apply([],e);var i,s,o,u,a=0,f=e[0],l=[],c=this.length;if(!v.support.checkClone&&c>1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a<c;a++)r.call(n&&v.nodeName(this[a],"table")?Lt(this[a],"tbody"):this[a],a===u?o:v.clone(o,!0,!0))}o=s=null,l.length&&v.each(l,function(e,t){t.src?v.ajax?v.ajax({url:t.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):v.error("no ajax"):v.globalEval((t.text||t.textContent||t.innerHTML||"").replace(Tt,"")),t.parentNode&&t.parentNode.removeChild(t)})}return this}}),v.buildFragment=function(e,n,r){var s,o,u,a=e[0];return n=n||i,n=!n.nodeType&&n[0]||n,n=n.ownerDocument||n,e.length===1&&typeof a=="string"&&a.length<512&&n===i&&a.charAt(0)==="<"&&!bt.test(a)&&(v.support.checkClone||!St.test(a))&&(v.support.html5Clone||!wt.test(a))&&(o=!0,s=v.fragments[a],u=s!==t),s||(s=n.createDocumentFragment(),v.clean(e,n,s,r),o&&(v.fragments[a]=u&&s)),{fragment:s,cacheable:o}},v.fragments={},v.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){v.fn[e]=function(n){var r,i=0,s=[],o=v(n),u=o.length,a=this.length===1&&this[0].parentNode;if((a==null||a&&a.nodeType===11&&a.childNodes.length===1)&&u===1)return o[t](this[0]),this;for(;i<u;i++)r=(i>0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1></$2>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]==="<table>"&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("<div>").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r<i;r++)n=e[r],Vn[n]=Vn[n]||[],Vn[n].unshift(t)},prefilter:function(e,t){t?Xn.unshift(e):Xn.push(e)}}),v.Tween=Yn,Yn.prototype={constructor:Yn,init:function(e,t,n,r,i,s){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=s||(v.cssNumber[n]?"":"px")},cur:function(){var e=Yn.propHooks[this.prop];return e&&e.get?e.get(this):Yn.propHooks._default.get(this)},run:function(e){var t,n=Yn.propHooks[this.prop];return this.options.duration?this.pos=t=v.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):Yn.propHooks._default.set(this),this}},Yn.prototype.init.prototype=Yn.prototype,Yn.propHooks={_default:{get:function(e){var t;return e.elem[e.prop]==null||!!e.elem.style&&e.elem.style[e.prop]!=null?(t=v.css(e.elem,e.prop,!1,""),!t||t==="auto"?0:t):e.elem[e.prop]},set:function(e){v.fx.step[e.prop]?v.fx.step[e.prop](e):e.elem.style&&(e.elem.style[v.cssProps[e.prop]]!=null||v.cssHooks[e.prop])?v.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},Yn.propHooks.scrollTop=Yn.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},v.each(["toggle","show","hide"],function(e,t){var n=v.fn[t];v.fn[t]=function(r,i,s){return r==null||typeof r=="boolean"||!e&&v.isFunction(r)&&v.isFunction(i)?n.apply(this,arguments):this.animate(Zn(t,!0),r,i,s)}}),v.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Gt).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=v.isEmptyObject(e),s=v.speed(t,n,r),o=function(){var t=Kn(this,v.extend({},e),s);i&&t.stop(!0)};return i||s.queue===!1?this.each(o):this.queue(s.queue,o)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return typeof e!="string"&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=e!=null&&e+"queueHooks",s=v.timers,o=v._data(this);if(n)o[n]&&o[n].stop&&i(o[n]);else for(n in o)o[n]&&o[n].stop&&Wn.test(n)&&i(o[n]);for(n=s.length;n--;)s[n].elem===this&&(e==null||s[n].queue===e)&&(s[n].anim.stop(r),t=!1,s.splice(n,1));(t||!r)&&v.dequeue(this,e)})}}),v.each({slideDown:Zn("show"),slideUp:Zn("hide"),slideToggle:Zn("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){v.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),v.speed=function(e,t,n){var r=e&&typeof e=="object"?v.extend({},e):{complete:n||!n&&t||v.isFunction(e)&&e,duration:e,easing:n&&t||t&&!v.isFunction(t)&&t};r.duration=v.fx.off?0:typeof r.duration=="number"?r.duration:r.duration in v.fx.speeds?v.fx.speeds[r.duration]:v.fx.speeds._default;if(r.queue==null||r.queue===!0)r.queue="fx";return r.old=r.complete,r.complete=function(){v.isFunction(r.old)&&r.old.call(this),r.queue&&v.dequeue(this,r.queue)},r},v.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},v.timers=[],v.fx=Yn.prototype.init,v.fx.tick=function(){var e,n=v.timers,r=0;qn=v.now();for(;r<n.length;r++)e=n[r],!e()&&n[r]===e&&n.splice(r--,1);n.length||v.fx.stop(),qn=t},v.fx.timer=function(e){e()&&v.timers.push(e)&&!Rn&&(Rn=setInterval(v.fx.tick,v.fx.interval))},v.fx.interval=13,v.fx.stop=function(){clearInterval(Rn),Rn=null},v.fx.speeds={slow:600,fast:200,_default:400},v.fx.step={},v.expr&&v.expr.filters&&(v.expr.filters.animated=function(e){return v.grep(v.timers,function(t){return e===t.elem}).length});var er=/^(?:body|html)$/i;v.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){v.offset.setOffset(this,e,t)});var n,r,i,s,o,u,a,f={top:0,left:0},l=this[0],c=l&&l.ownerDocument;if(!c)return;return(r=c.body)===l?v.offset.bodyOffset(l):(n=c.documentElement,v.contains(n,l)?(typeof l.getBoundingClientRect!="undefined"&&(f=l.getBoundingClientRect()),i=tr(c),s=n.clientTop||r.clientTop||0,o=n.clientLeft||r.clientLeft||0,u=i.pageYOffset||n.scrollTop,a=i.pageXOffset||n.scrollLeft,{top:f.top+u-s,left:f.left+a-o}):f)},v.offset={bodyOffset:function(e){var t=e.offsetTop,n=e.offsetLeft;return v.support.doesNotIncludeMarginInBodyOffset&&(t+=parseFloat(v.css(e,"marginTop"))||0,n+=parseFloat(v.css(e,"marginLeft"))||0),{top:t,left:n}},setOffset:function(e,t,n){var r=v.css(e,"position");r==="static"&&(e.style.position="relative");var i=v(e),s=i.offset(),o=v.css(e,"top"),u=v.css(e,"left"),a=(r==="absolute"||r==="fixed")&&v.inArray("auto",[o,u])>-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window);
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery-ui-1.9.2.custom.min.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery-ui-1.9.2.custom.min.js new file mode 100755 index 000000000..9b3b84deb --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery-ui-1.9.2.custom.min.js @@ -0,0 +1,6 @@ +/*! jQuery UI - v1.9.2 - 2012-11-23 +* http://jqueryui.com +* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.slider.js, jquery.ui.sortable.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js +* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */ + +(function(e,t){function i(t,n){var r,i,o,u=t.nodeName.toLowerCase();return"area"===u?(r=t.parentNode,i=r.name,!t.href||!i||r.nodeName.toLowerCase()!=="map"?!1:(o=e("img[usemap=#"+i+"]")[0],!!o&&s(o))):(/input|select|textarea|button|object/.test(u)?!t.disabled:"a"===u?t.href||n:n)&&s(t)}function s(t){return e.expr.filters.visible(t)&&!e(t).parents().andSelf().filter(function(){return e.css(this,"visibility")==="hidden"}).length}var n=0,r=/^ui-id-\d+$/;e.ui=e.ui||{};if(e.ui.version)return;e.extend(e.ui,{version:"1.9.2",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({_focus:e.fn.focus,focus:function(t,n){return typeof t=="number"?this.each(function(){var r=this;setTimeout(function(){e(r).focus(),n&&n.call(r)},t)}):this._focus.apply(this,arguments)},scrollParent:function(){var t;return e.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?t=this.parents().filter(function(){return/(relative|absolute|fixed)/.test(e.css(this,"position"))&&/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0):t=this.parents().filter(function(){return/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!t.length?e(document):t},zIndex:function(n){if(n!==t)return this.css("zIndex",n);if(this.length){var r=e(this[0]),i,s;while(r.length&&r[0]!==document){i=r.css("position");if(i==="absolute"||i==="relative"||i==="fixed"){s=parseInt(r.css("zIndex"),10);if(!isNaN(s)&&s!==0)return s}r=r.parent()}}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++n)})},removeUniqueId:function(){return this.each(function(){r.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(n){return!!e.data(n,t)}}):function(t,n,r){return!!e.data(t,r[3])},focusable:function(t){return i(t,!isNaN(e.attr(t,"tabindex")))},tabbable:function(t){var n=e.attr(t,"tabindex"),r=isNaN(n);return(r||n>=0)&&i(t,!r)}}),e(function(){var t=document.body,n=t.appendChild(n=document.createElement("div"));n.offsetHeight,e.extend(n.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0}),e.support.minHeight=n.offsetHeight===100,e.support.selectstart="onselectstart"in n,t.removeChild(n).style.display="none"}),e("<a>").outerWidth(1).jquery||e.each(["Width","Height"],function(n,r){function u(t,n,r,s){return e.each(i,function(){n-=parseFloat(e.css(t,"padding"+this))||0,r&&(n-=parseFloat(e.css(t,"border"+this+"Width"))||0),s&&(n-=parseFloat(e.css(t,"margin"+this))||0)}),n}var i=r==="Width"?["Left","Right"]:["Top","Bottom"],s=r.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+r]=function(n){return n===t?o["inner"+r].call(this):this.each(function(){e(this).css(s,u(this,n)+"px")})},e.fn["outer"+r]=function(t,n){return typeof t!="number"?o["outer"+r].call(this,t):this.each(function(){e(this).css(s,u(this,t,!0,n)+"px")})}}),e("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(n){return arguments.length?t.call(this,e.camelCase(n)):t.call(this)}}(e.fn.removeData)),function(){var t=/msie ([\w.]+)/.exec(navigator.userAgent.toLowerCase())||[];e.ui.ie=t.length?!0:!1,e.ui.ie6=parseFloat(t[1],10)===6}(),e.fn.extend({disableSelection:function(){return this.bind((e.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),e.extend(e.ui,{plugin:{add:function(t,n,r){var i,s=e.ui[t].prototype;for(i in r)s.plugins[i]=s.plugins[i]||[],s.plugins[i].push([n,r[i]])},call:function(e,t,n){var r,i=e.plugins[t];if(!i||!e.element[0].parentNode||e.element[0].parentNode.nodeType===11)return;for(r=0;r<i.length;r++)e.options[i[r][0]]&&i[r][1].apply(e.element,n)}},contains:e.contains,hasScroll:function(t,n){if(e(t).css("overflow")==="hidden")return!1;var r=n&&n==="left"?"scrollLeft":"scrollTop",i=!1;return t[r]>0?!0:(t[r]=1,i=t[r]>0,t[r]=0,i)},isOverAxis:function(e,t,n){return e>t&&e<t+n},isOver:function(t,n,r,i,s,o){return e.ui.isOverAxis(t,r,s)&&e.ui.isOverAxis(n,i,o)}})})(jQuery);(function(e,t){var n=0,r=Array.prototype.slice,i=e.cleanData;e.cleanData=function(t){for(var n=0,r;(r=t[n])!=null;n++)try{e(r).triggerHandler("remove")}catch(s){}i(t)},e.widget=function(t,n,r){var i,s,o,u,a=t.split(".")[0];t=t.split(".")[1],i=a+"-"+t,r||(r=n,n=e.Widget),e.expr[":"][i.toLowerCase()]=function(t){return!!e.data(t,i)},e[a]=e[a]||{},s=e[a][t],o=e[a][t]=function(e,t){if(!this._createWidget)return new o(e,t);arguments.length&&this._createWidget(e,t)},e.extend(o,s,{version:r.version,_proto:e.extend({},r),_childConstructors:[]}),u=new n,u.options=e.widget.extend({},u.options),e.each(r,function(t,i){e.isFunction(i)&&(r[t]=function(){var e=function(){return n.prototype[t].apply(this,arguments)},r=function(e){return n.prototype[t].apply(this,e)};return function(){var t=this._super,n=this._superApply,s;return this._super=e,this._superApply=r,s=i.apply(this,arguments),this._super=t,this._superApply=n,s}}())}),o.prototype=e.widget.extend(u,{widgetEventPrefix:s?u.widgetEventPrefix:t},r,{constructor:o,namespace:a,widgetName:t,widgetBaseClass:i,widgetFullName:i}),s?(e.each(s._childConstructors,function(t,n){var r=n.prototype;e.widget(r.namespace+"."+r.widgetName,o,n._proto)}),delete s._childConstructors):n._childConstructors.push(o),e.widget.bridge(t,o)},e.widget.extend=function(n){var i=r.call(arguments,1),s=0,o=i.length,u,a;for(;s<o;s++)for(u in i[s])a=i[s][u],i[s].hasOwnProperty(u)&&a!==t&&(e.isPlainObject(a)?n[u]=e.isPlainObject(n[u])?e.widget.extend({},n[u],a):e.widget.extend({},a):n[u]=a);return n},e.widget.bridge=function(n,i){var s=i.prototype.widgetFullName||n;e.fn[n]=function(o){var u=typeof o=="string",a=r.call(arguments,1),f=this;return o=!u&&a.length?e.widget.extend.apply(null,[o].concat(a)):o,u?this.each(function(){var r,i=e.data(this,s);if(!i)return e.error("cannot call methods on "+n+" prior to initialization; "+"attempted to call method '"+o+"'");if(!e.isFunction(i[o])||o.charAt(0)==="_")return e.error("no such method '"+o+"' for "+n+" widget instance");r=i[o].apply(i,a);if(r!==i&&r!==t)return f=r&&r.jquery?f.pushStack(r.get()):r,!1}):this.each(function(){var t=e.data(this,s);t?t.option(o||{})._init():e.data(this,s,new i(o,this))}),f}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{disabled:!1,create:null},_createWidget:function(t,r){r=e(r||this.defaultElement||this)[0],this.element=e(r),this.uuid=n++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this.bindings=e(),this.hoverable=e(),this.focusable=e(),r!==this&&(e.data(r,this.widgetName,this),e.data(r,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===r&&this.destroy()}}),this.document=e(r.style?r.ownerDocument:r.document||r),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(n,r){var i=n,s,o,u;if(arguments.length===0)return e.widget.extend({},this.options);if(typeof n=="string"){i={},s=n.split("."),n=s.shift();if(s.length){o=i[n]=e.widget.extend({},this.options[n]);for(u=0;u<s.length-1;u++)o[s[u]]=o[s[u]]||{},o=o[s[u]];n=s.pop();if(r===t)return o[n]===t?null:o[n];o[n]=r}else{if(r===t)return this.options[n]===t?null:this.options[n];i[n]=r}}return this._setOptions(i),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,e==="disabled"&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!t).attr("aria-disabled",t),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(t,n,r){var i,s=this;typeof t!="boolean"&&(r=n,n=t,t=!1),r?(n=i=e(n),this.bindings=this.bindings.add(n)):(r=n,n=this.element,i=this.widget()),e.each(r,function(r,o){function u(){if(!t&&(s.options.disabled===!0||e(this).hasClass("ui-state-disabled")))return;return(typeof o=="string"?s[o]:o).apply(s,arguments)}typeof o!="string"&&(u.guid=o.guid=o.guid||u.guid||e.guid++);var a=r.match(/^(\w+)\s*(.*)$/),f=a[1]+s.eventNamespace,l=a[2];l?i.delegate(l,f,u):n.bind(f,u)})},_off:function(e,t){t=(t||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.unbind(t).undelegate(t)},_delay:function(e,t){function n(){return(typeof e=="string"?r[e]:e).apply(r,arguments)}var r=this;return setTimeout(n,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,n,r){var i,s,o=this.options[t];r=r||{},n=e.Event(n),n.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),n.target=this.element[0],s=n.originalEvent;if(s)for(i in s)i in n||(n[i]=s[i]);return this.element.trigger(n,r),!(e.isFunction(o)&&o.apply(this.element[0],[n].concat(r))===!1||n.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,n){e.Widget.prototype["_"+t]=function(r,i,s){typeof i=="string"&&(i={effect:i});var o,u=i?i===!0||typeof i=="number"?n:i.effect||n:t;i=i||{},typeof i=="number"&&(i={duration:i}),o=!e.isEmptyObject(i),i.complete=s,i.delay&&r.delay(i.delay),o&&e.effects&&(e.effects.effect[u]||e.uiBackCompat!==!1&&e.effects[u])?r[t](i):u!==t&&r[u]?r[u](i.duration,i.easing,s):r.queue(function(n){e(this)[t](),s&&s.call(r[0]),n()})}}),e.uiBackCompat!==!1&&(e.Widget.prototype._getCreateOptions=function(){return e.metadata&&e.metadata.get(this.element[0])[this.widgetName]})})(jQuery);(function(e,t){var n=!1;e(document).mouseup(function(e){n=!1}),e.widget("ui.mouse",{version:"1.9.2",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var t=this;this.element.bind("mousedown."+this.widgetName,function(e){return t._mouseDown(e)}).bind("click."+this.widgetName,function(n){if(!0===e.data(n.target,t.widgetName+".preventClickEvent"))return e.removeData(n.target,t.widgetName+".preventClickEvent"),n.stopImmediatePropagation(),!1}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(t){if(n)return;this._mouseStarted&&this._mouseUp(t),this._mouseDownEvent=t;var r=this,i=t.which===1,s=typeof this.options.cancel=="string"&&t.target.nodeName?e(t.target).closest(this.options.cancel).length:!1;if(!i||s||!this._mouseCapture(t))return!0;this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){r.mouseDelayMet=!0},this.options.delay));if(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)){this._mouseStarted=this._mouseStart(t)!==!1;if(!this._mouseStarted)return t.preventDefault(),!0}return!0===e.data(t.target,this.widgetName+".preventClickEvent")&&e.removeData(t.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(e){return r._mouseMove(e)},this._mouseUpDelegate=function(e){return r._mouseUp(e)},e(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),t.preventDefault(),n=!0,!0},_mouseMove:function(t){return!e.ui.ie||document.documentMode>=9||!!t.button?this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted):this._mouseUp(t)},_mouseUp:function(t){return e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(e){return this.mouseDelayMet},_mouseStart:function(e){},_mouseDrag:function(e){},_mouseStop:function(e){},_mouseCapture:function(e){return!0}})})(jQuery);(function(e,t){function h(e,t,n){return[parseInt(e[0],10)*(l.test(e[0])?t/100:1),parseInt(e[1],10)*(l.test(e[1])?n/100:1)]}function p(t,n){return parseInt(e.css(t,n),10)||0}e.ui=e.ui||{};var n,r=Math.max,i=Math.abs,s=Math.round,o=/left|center|right/,u=/top|center|bottom/,a=/[\+\-]\d+%?/,f=/^\w+/,l=/%$/,c=e.fn.position;e.position={scrollbarWidth:function(){if(n!==t)return n;var r,i,s=e("<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),o=s.children()[0];return e("body").append(s),r=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,r===i&&(i=s[0].clientWidth),s.remove(),n=r-i},getScrollInfo:function(t){var n=t.isWindow?"":t.element.css("overflow-x"),r=t.isWindow?"":t.element.css("overflow-y"),i=n==="scroll"||n==="auto"&&t.width<t.element[0].scrollWidth,s=r==="scroll"||r==="auto"&&t.height<t.element[0].scrollHeight;return{width:i?e.position.scrollbarWidth():0,height:s?e.position.scrollbarWidth():0}},getWithinInfo:function(t){var n=e(t||window),r=e.isWindow(n[0]);return{element:n,isWindow:r,offset:n.offset()||{left:0,top:0},scrollLeft:n.scrollLeft(),scrollTop:n.scrollTop(),width:r?n.width():n.outerWidth(),height:r?n.height():n.outerHeight()}}},e.fn.position=function(t){if(!t||!t.of)return c.apply(this,arguments);t=e.extend({},t);var n,l,d,v,m,g=e(t.of),y=e.position.getWithinInfo(t.within),b=e.position.getScrollInfo(y),w=g[0],E=(t.collision||"flip").split(" "),S={};return w.nodeType===9?(l=g.width(),d=g.height(),v={top:0,left:0}):e.isWindow(w)?(l=g.width(),d=g.height(),v={top:g.scrollTop(),left:g.scrollLeft()}):w.preventDefault?(t.at="left top",l=d=0,v={top:w.pageY,left:w.pageX}):(l=g.outerWidth(),d=g.outerHeight(),v=g.offset()),m=e.extend({},v),e.each(["my","at"],function(){var e=(t[this]||"").split(" "),n,r;e.length===1&&(e=o.test(e[0])?e.concat(["center"]):u.test(e[0])?["center"].concat(e):["center","center"]),e[0]=o.test(e[0])?e[0]:"center",e[1]=u.test(e[1])?e[1]:"center",n=a.exec(e[0]),r=a.exec(e[1]),S[this]=[n?n[0]:0,r?r[0]:0],t[this]=[f.exec(e[0])[0],f.exec(e[1])[0]]}),E.length===1&&(E[1]=E[0]),t.at[0]==="right"?m.left+=l:t.at[0]==="center"&&(m.left+=l/2),t.at[1]==="bottom"?m.top+=d:t.at[1]==="center"&&(m.top+=d/2),n=h(S.at,l,d),m.left+=n[0],m.top+=n[1],this.each(function(){var o,u,a=e(this),f=a.outerWidth(),c=a.outerHeight(),w=p(this,"marginLeft"),x=p(this,"marginTop"),T=f+w+p(this,"marginRight")+b.width,N=c+x+p(this,"marginBottom")+b.height,C=e.extend({},m),k=h(S.my,a.outerWidth(),a.outerHeight());t.my[0]==="right"?C.left-=f:t.my[0]==="center"&&(C.left-=f/2),t.my[1]==="bottom"?C.top-=c:t.my[1]==="center"&&(C.top-=c/2),C.left+=k[0],C.top+=k[1],e.support.offsetFractions||(C.left=s(C.left),C.top=s(C.top)),o={marginLeft:w,marginTop:x},e.each(["left","top"],function(r,i){e.ui.position[E[r]]&&e.ui.position[E[r]][i](C,{targetWidth:l,targetHeight:d,elemWidth:f,elemHeight:c,collisionPosition:o,collisionWidth:T,collisionHeight:N,offset:[n[0]+k[0],n[1]+k[1]],my:t.my,at:t.at,within:y,elem:a})}),e.fn.bgiframe&&a.bgiframe(),t.using&&(u=function(e){var n=v.left-C.left,s=n+l-f,o=v.top-C.top,u=o+d-c,h={target:{element:g,left:v.left,top:v.top,width:l,height:d},element:{element:a,left:C.left,top:C.top,width:f,height:c},horizontal:s<0?"left":n>0?"right":"center",vertical:u<0?"top":o>0?"bottom":"middle"};l<f&&i(n+s)<l&&(h.horizontal="center"),d<c&&i(o+u)<d&&(h.vertical="middle"),r(i(n),i(s))>r(i(o),i(u))?h.important="horizontal":h.important="vertical",t.using.call(this,e,h)}),a.offset(e.extend(C,{using:u}))})},e.ui.position={fit:{left:function(e,t){var n=t.within,i=n.isWindow?n.scrollLeft:n.offset.left,s=n.width,o=e.left-t.collisionPosition.marginLeft,u=i-o,a=o+t.collisionWidth-s-i,f;t.collisionWidth>s?u>0&&a<=0?(f=e.left+u+t.collisionWidth-s-i,e.left+=u-f):a>0&&u<=0?e.left=i:u>a?e.left=i+s-t.collisionWidth:e.left=i:u>0?e.left+=u:a>0?e.left-=a:e.left=r(e.left-o,e.left)},top:function(e,t){var n=t.within,i=n.isWindow?n.scrollTop:n.offset.top,s=t.within.height,o=e.top-t.collisionPosition.marginTop,u=i-o,a=o+t.collisionHeight-s-i,f;t.collisionHeight>s?u>0&&a<=0?(f=e.top+u+t.collisionHeight-s-i,e.top+=u-f):a>0&&u<=0?e.top=i:u>a?e.top=i+s-t.collisionHeight:e.top=i:u>0?e.top+=u:a>0?e.top-=a:e.top=r(e.top-o,e.top)}},flip:{left:function(e,t){var n=t.within,r=n.offset.left+n.scrollLeft,s=n.width,o=n.isWindow?n.scrollLeft:n.offset.left,u=e.left-t.collisionPosition.marginLeft,a=u-o,f=u+t.collisionWidth-s-o,l=t.my[0]==="left"?-t.elemWidth:t.my[0]==="right"?t.elemWidth:0,c=t.at[0]==="left"?t.targetWidth:t.at[0]==="right"?-t.targetWidth:0,h=-2*t.offset[0],p,d;if(a<0){p=e.left+l+c+h+t.collisionWidth-s-r;if(p<0||p<i(a))e.left+=l+c+h}else if(f>0){d=e.left-t.collisionPosition.marginLeft+l+c+h-o;if(d>0||i(d)<f)e.left+=l+c+h}},top:function(e,t){var n=t.within,r=n.offset.top+n.scrollTop,s=n.height,o=n.isWindow?n.scrollTop:n.offset.top,u=e.top-t.collisionPosition.marginTop,a=u-o,f=u+t.collisionHeight-s-o,l=t.my[1]==="top",c=l?-t.elemHeight:t.my[1]==="bottom"?t.elemHeight:0,h=t.at[1]==="top"?t.targetHeight:t.at[1]==="bottom"?-t.targetHeight:0,p=-2*t.offset[1],d,v;a<0?(v=e.top+c+h+p+t.collisionHeight-s-r,e.top+c+h+p>a&&(v<0||v<i(a))&&(e.top+=c+h+p)):f>0&&(d=e.top-t.collisionPosition.marginTop+c+h+p-o,e.top+c+h+p>f&&(d>0||i(d)<f)&&(e.top+=c+h+p))}},flipfit:{left:function(){e.ui.position.flip.left.apply(this,arguments),e.ui.position.fit.left.apply(this,arguments)},top:function(){e.ui.position.flip.top.apply(this,arguments),e.ui.position.fit.top.apply(this,arguments)}}},function(){var t,n,r,i,s,o=document.getElementsByTagName("body")[0],u=document.createElement("div");t=document.createElement(o?"div":"body"),r={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},o&&e.extend(r,{position:"absolute",left:"-1000px",top:"-1000px"});for(s in r)t.style[s]=r[s];t.appendChild(u),n=o||document.documentElement,n.insertBefore(t,n.firstChild),u.style.cssText="position: absolute; left: 10.7432222px;",i=e(u).offset().left,e.support.offsetFractions=i>10&&i<11,t.innerHTML="",n.removeChild(t)}(),e.uiBackCompat!==!1&&function(e){var n=e.fn.position;e.fn.position=function(r){if(!r||!r.offset)return n.call(this,r);var i=r.offset.split(" "),s=r.at.split(" ");return i.length===1&&(i[1]=i[0]),/^\d/.test(i[0])&&(i[0]="+"+i[0]),/^\d/.test(i[1])&&(i[1]="+"+i[1]),s.length===1&&(/left|center|right/.test(s[0])?s[1]="center":(s[1]=s[0],s[0]="center")),n.call(this,e.extend(r,{at:s[0]+i[0]+" "+s[1]+i[1],offset:t}))}}(jQuery)})(jQuery);(function(e,t){var n=0,r={},i={};r.height=r.paddingTop=r.paddingBottom=r.borderTopWidth=r.borderBottomWidth="hide",i.height=i.paddingTop=i.paddingBottom=i.borderTopWidth=i.borderBottomWidth="show",e.widget("ui.accordion",{version:"1.9.2",options:{active:0,animate:{},collapsible:!1,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},_create:function(){var t=this.accordionId="ui-accordion-"+(this.element.attr("id")||++n),r=this.options;this.prevShow=this.prevHide=e(),this.element.addClass("ui-accordion ui-widget ui-helper-reset"),this.headers=this.element.find(r.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all"),this._hoverable(this.headers),this._focusable(this.headers),this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").hide(),!r.collapsible&&(r.active===!1||r.active==null)&&(r.active=0),r.active<0&&(r.active+=this.headers.length),this.active=this._findActive(r.active).addClass("ui-accordion-header-active ui-state-active").toggleClass("ui-corner-all ui-corner-top"),this.active.next().addClass("ui-accordion-content-active").show(),this._createIcons(),this.refresh(),this.element.attr("role","tablist"),this.headers.attr("role","tab").each(function(n){var r=e(this),i=r.attr("id"),s=r.next(),o=s.attr("id");i||(i=t+"-header-"+n,r.attr("id",i)),o||(o=t+"-panel-"+n,s.attr("id",o)),r.attr("aria-controls",o),s.attr("aria-labelledby",i)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false",tabIndex:-1}).next().attr({"aria-expanded":"false","aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true",tabIndex:0}).next().attr({"aria-expanded":"true","aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._on(this.headers,{keydown:"_keydown"}),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._setupEvents(r.event)},_getCreateEventData:function(){return{header:this.active,content:this.active.length?this.active.next():e()}},_createIcons:function(){var t=this.options.icons;t&&(e("<span>").addClass("ui-accordion-header-icon ui-icon "+t.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(t.header).addClass(t.activeHeader),this.headers.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var e;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this._destroyIcons(),e=this.headers.next().css("display","").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this.options.heightStyle!=="content"&&e.css("height","")},_setOption:function(e,t){if(e==="active"){this._activate(t);return}e==="event"&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(t)),this._super(e,t),e==="collapsible"&&!t&&this.options.active===!1&&this._activate(0),e==="icons"&&(this._destroyIcons(),t&&this._createIcons()),e==="disabled"&&this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!t)},_keydown:function(t){if(t.altKey||t.ctrlKey)return;var n=e.ui.keyCode,r=this.headers.length,i=this.headers.index(t.target),s=!1;switch(t.keyCode){case n.RIGHT:case n.DOWN:s=this.headers[(i+1)%r];break;case n.LEFT:case n.UP:s=this.headers[(i-1+r)%r];break;case n.SPACE:case n.ENTER:this._eventHandler(t);break;case n.HOME:s=this.headers[0];break;case n.END:s=this.headers[r-1]}s&&(e(t.target).attr("tabIndex",-1),e(s).attr("tabIndex",0),s.focus(),t.preventDefault())},_panelKeyDown:function(t){t.keyCode===e.ui.keyCode.UP&&t.ctrlKey&&e(t.currentTarget).prev().focus()},refresh:function(){var t,n,r=this.options.heightStyle,i=this.element.parent();r==="fill"?(e.support.minHeight||(n=i.css("overflow"),i.css("overflow","hidden")),t=i.height(),this.element.siblings(":visible").each(function(){var n=e(this),r=n.css("position");if(r==="absolute"||r==="fixed")return;t-=n.outerHeight(!0)}),n&&i.css("overflow",n),this.headers.each(function(){t-=e(this).outerHeight(!0)}),this.headers.next().each(function(){e(this).height(Math.max(0,t-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):r==="auto"&&(t=0,this.headers.next().each(function(){t=Math.max(t,e(this).css("height","").height())}).height(t))},_activate:function(t){var n=this._findActive(t)[0];if(n===this.active[0])return;n=n||this.active[0],this._eventHandler({target:n,currentTarget:n,preventDefault:e.noop})},_findActive:function(t){return typeof t=="number"?this.headers.eq(t):e()},_setupEvents:function(t){var n={};if(!t)return;e.each(t.split(" "),function(e,t){n[t]="_eventHandler"}),this._on(this.headers,n)},_eventHandler:function(t){var n=this.options,r=this.active,i=e(t.currentTarget),s=i[0]===r[0],o=s&&n.collapsible,u=o?e():i.next(),a=r.next(),f={oldHeader:r,oldPanel:a,newHeader:o?e():i,newPanel:u};t.preventDefault();if(s&&!n.collapsible||this._trigger("beforeActivate",t,f)===!1)return;n.active=o?!1:this.headers.index(i),this.active=s?e():i,this._toggle(f),r.removeClass("ui-accordion-header-active ui-state-active"),n.icons&&r.children(".ui-accordion-header-icon").removeClass(n.icons.activeHeader).addClass(n.icons.header),s||(i.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),n.icons&&i.children(".ui-accordion-header-icon").removeClass(n.icons.header).addClass(n.icons.activeHeader),i.next().addClass("ui-accordion-content-active"))},_toggle:function(t){var n=t.newPanel,r=this.prevShow.length?this.prevShow:t.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=n,this.prevHide=r,this.options.animate?this._animate(n,r,t):(r.hide(),n.show(),this._toggleComplete(t)),r.attr({"aria-expanded":"false","aria-hidden":"true"}),r.prev().attr("aria-selected","false"),n.length&&r.length?r.prev().attr("tabIndex",-1):n.length&&this.headers.filter(function(){return e(this).attr("tabIndex")===0}).attr("tabIndex",-1),n.attr({"aria-expanded":"true","aria-hidden":"false"}).prev().attr({"aria-selected":"true",tabIndex:0})},_animate:function(e,t,n){var s,o,u,a=this,f=0,l=e.length&&(!t.length||e.index()<t.index()),c=this.options.animate||{},h=l&&c.down||c,p=function(){a._toggleComplete(n)};typeof h=="number"&&(u=h),typeof h=="string"&&(o=h),o=o||h.easing||c.easing,u=u||h.duration||c.duration;if(!t.length)return e.animate(i,u,o,p);if(!e.length)return t.animate(r,u,o,p);s=e.show().outerHeight(),t.animate(r,{duration:u,easing:o,step:function(e,t){t.now=Math.round(e)}}),e.hide().animate(i,{duration:u,easing:o,complete:p,step:function(e,n){n.now=Math.round(e),n.prop!=="height"?f+=n.now:a.options.heightStyle!=="content"&&(n.now=Math.round(s-t.outerHeight()-f),f=0)}})},_toggleComplete:function(e){var t=e.oldPanel;t.removeClass("ui-accordion-content-active").prev().removeClass("ui-corner-top").addClass("ui-corner-all"),t.length&&(t.parent()[0].className=t.parent()[0].className),this._trigger("activate",null,e)}}),e.uiBackCompat!==!1&&(function(e,t){e.extend(t.options,{navigation:!1,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}});var n=t._create;t._create=function(){if(this.options.navigation){var t=this,r=this.element.find(this.options.header),i=r.next(),s=r.add(i).find("a").filter(this.options.navigationFilter)[0];s&&r.add(i).each(function(n){if(e.contains(this,s))return t.options.active=Math.floor(n/2),!1})}n.call(this)}}(jQuery,jQuery.ui.accordion.prototype),function(e,t){e.extend(t.options,{heightStyle:null,autoHeight:!0,clearStyle:!1,fillSpace:!1});var n=t._create,r=t._setOption;e.extend(t,{_create:function(){this.options.heightStyle=this.options.heightStyle||this._mergeHeightStyle(),n.call(this)},_setOption:function(e){if(e==="autoHeight"||e==="clearStyle"||e==="fillSpace")this.options.heightStyle=this._mergeHeightStyle();r.apply(this,arguments)},_mergeHeightStyle:function(){var e=this.options;if(e.fillSpace)return"fill";if(e.clearStyle)return"content";if(e.autoHeight)return"auto"}})}(jQuery,jQuery.ui.accordion.prototype),function(e,t){e.extend(t.options.icons,{activeHeader:null,headerSelected:"ui-icon-triangle-1-s"});var n=t._createIcons;t._createIcons=function(){this.options.icons&&(this.options.icons.activeHeader=this.options.icons.activeHeader||this.options.icons.headerSelected),n.call(this)}}(jQuery,jQuery.ui.accordion.prototype),function(e,t){t.activate=t._activate;var n=t._findActive;t._findActive=function(e){return e===-1&&(e=!1),e&&typeof e!="number"&&(e=this.headers.index(this.headers.filter(e)),e===-1&&(e=!1)),n.call(this,e)}}(jQuery,jQuery.ui.accordion.prototype),jQuery.ui.accordion.prototype.resize=jQuery.ui.accordion.prototype.refresh,function(e,t){e.extend(t.options,{change:null,changestart:null});var n=t._trigger;t._trigger=function(e,t,r){var i=n.apply(this,arguments);return i?(e==="beforeActivate"?i=n.call(this,"changestart",t,{oldHeader:r.oldHeader,oldContent:r.oldPanel,newHeader:r.newHeader,newContent:r.newPanel}):e==="activate"&&(i=n.call(this,"change",t,{oldHeader:r.oldHeader,oldContent:r.oldPanel,newHeader:r.newHeader,newContent:r.newPanel})),i):!1}}(jQuery,jQuery.ui.accordion.prototype),function(e,t){e.extend(t.options,{animate:null,animated:"slide"});var n=t._create;t._create=function(){var e=this.options;e.animate===null&&(e.animated?e.animated==="slide"?e.animate=300:e.animated==="bounceslide"?e.animate={duration:200,down:{easing:"easeOutBounce",duration:1e3}}:e.animate=e.animated:e.animate=!1),n.call(this)}}(jQuery,jQuery.ui.accordion.prototype))})(jQuery);(function(e,t){var n=0;e.widget("ui.autocomplete",{version:"1.9.2",defaultElement:"<input>",options:{appendTo:"body",autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},pending:0,_create:function(){var t,n,r;this.isMultiLine=this._isMultiLine(),this.valueMethod=this.element[this.element.is("input,textarea")?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on(this.element,{keydown:function(i){if(this.element.prop("readOnly")){t=!0,r=!0,n=!0;return}t=!1,r=!1,n=!1;var s=e.ui.keyCode;switch(i.keyCode){case s.PAGE_UP:t=!0,this._move("previousPage",i);break;case s.PAGE_DOWN:t=!0,this._move("nextPage",i);break;case s.UP:t=!0,this._keyEvent("previous",i);break;case s.DOWN:t=!0,this._keyEvent("next",i);break;case s.ENTER:case s.NUMPAD_ENTER:this.menu.active&&(t=!0,i.preventDefault(),this.menu.select(i));break;case s.TAB:this.menu.active&&this.menu.select(i);break;case s.ESCAPE:this.menu.element.is(":visible")&&(this._value(this.term),this.close(i),i.preventDefault());break;default:n=!0,this._searchTimeout(i)}},keypress:function(r){if(t){t=!1,r.preventDefault();return}if(n)return;var i=e.ui.keyCode;switch(r.keyCode){case i.PAGE_UP:this._move("previousPage",r);break;case i.PAGE_DOWN:this._move("nextPage",r);break;case i.UP:this._keyEvent("previous",r);break;case i.DOWN:this._keyEvent("next",r)}},input:function(e){if(r){r=!1,e.preventDefault();return}this._searchTimeout(e)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(e){if(this.cancelBlur){delete this.cancelBlur;return}clearTimeout(this.searching),this.close(e),this._change(e)}}),this._initSource(),this.menu=e("<ul>").addClass("ui-autocomplete").appendTo(this.document.find(this.options.appendTo||"body")[0]).menu({input:e(),role:null}).zIndex(this.element.zIndex()+1).hide().data("menu"),this._on(this.menu.element,{mousedown:function(t){t.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur});var n=this.menu.element[0];e(t.target).closest(".ui-menu-item").length||this._delay(function(){var t=this;this.document.one("mousedown",function(r){r.target!==t.element[0]&&r.target!==n&&!e.contains(n,r.target)&&t.close()})})},menufocus:function(t,n){if(this.isNewMenu){this.isNewMenu=!1;if(t.originalEvent&&/^mouse/.test(t.originalEvent.type)){this.menu.blur(),this.document.one("mousemove",function(){e(t.target).trigger(t.originalEvent)});return}}var r=n.item.data("ui-autocomplete-item")||n.item.data("item.autocomplete");!1!==this._trigger("focus",t,{item:r})?t.originalEvent&&/^key/.test(t.originalEvent.type)&&this._value(r.value):this.liveRegion.text(r.value)},menuselect:function(e,t){var n=t.item.data("ui-autocomplete-item")||t.item.data("item.autocomplete"),r=this.previous;this.element[0]!==this.document[0].activeElement&&(this.element.focus(),this.previous=r,this._delay(function(){this.previous=r,this.selectedItem=n})),!1!==this._trigger("select",e,{item:n})&&this._value(n.value),this.term=this._value(),this.close(e),this.selectedItem=n}}),this.liveRegion=e("<span>",{role:"status","aria-live":"polite"}).addClass("ui-helper-hidden-accessible").insertAfter(this.element),e.fn.bgiframe&&this.menu.element.bgiframe(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(e,t){this._super(e,t),e==="source"&&this._initSource(),e==="appendTo"&&this.menu.element.appendTo(this.document.find(t||"body")[0]),e==="disabled"&&t&&this.xhr&&this.xhr.abort()},_isMultiLine:function(){return this.element.is("textarea")?!0:this.element.is("input")?!1:this.element.prop("isContentEditable")},_initSource:function(){var t,n,r=this;e.isArray(this.options.source)?(t=this.options.source,this.source=function(n,r){r(e.ui.autocomplete.filter(t,n.term))}):typeof this.options.source=="string"?(n=this.options.source,this.source=function(t,i){r.xhr&&r.xhr.abort(),r.xhr=e.ajax({url:n,data:t,dataType:"json",success:function(e){i(e)},error:function(){i([])}})}):this.source=this.options.source},_searchTimeout:function(e){clearTimeout(this.searching),this.searching=this._delay(function(){this.term!==this._value()&&(this.selectedItem=null,this.search(null,e))},this.options.delay)},search:function(e,t){e=e!=null?e:this._value(),this.term=this._value();if(e.length<this.options.minLength)return this.close(t);if(this._trigger("search",t)===!1)return;return this._search(e)},_search:function(e){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.cancelSearch=!1,this.source({term:e},this._response())},_response:function(){var e=this,t=++n;return function(r){t===n&&e.__response(r),e.pending--,e.pending||e.element.removeClass("ui-autocomplete-loading")}},__response:function(e){e&&(e=this._normalize(e)),this._trigger("response",null,{content:e}),!this.options.disabled&&e&&e.length&&!this.cancelSearch?(this._suggest(e),this._trigger("open")):this._close()},close:function(e){this.cancelSearch=!0,this._close(e)},_close:function(e){this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.blur(),this.isNewMenu=!0,this._trigger("close",e))},_change:function(e){this.previous!==this._value()&&this._trigger("change",e,{item:this.selectedItem})},_normalize:function(t){return t.length&&t[0].label&&t[0].value?t:e.map(t,function(t){return typeof t=="string"?{label:t,value:t}:e.extend({label:t.label||t.value,value:t.value||t.label},t)})},_suggest:function(t){var n=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(n,t),this.menu.refresh(),n.show(),this._resizeMenu(),n.position(e.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next()},_resizeMenu:function(){var e=this.menu.element;e.outerWidth(Math.max(e.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(t,n){var r=this;e.each(n,function(e,n){r._renderItemData(t,n)})},_renderItemData:function(e,t){return this._renderItem(e,t).data("ui-autocomplete-item",t)},_renderItem:function(t,n){return e("<li>").append(e("<a>").text(n.label)).appendTo(t)},_move:function(e,t){if(!this.menu.element.is(":visible")){this.search(null,t);return}if(this.menu.isFirstItem()&&/^previous/.test(e)||this.menu.isLastItem()&&/^next/.test(e)){this._value(this.term),this.menu.blur();return}this.menu[e](t)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(e,t){if(!this.isMultiLine||this.menu.element.is(":visible"))this._move(e,t),t.preventDefault()}}),e.extend(e.ui.autocomplete,{escapeRegex:function(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(t,n){var r=new RegExp(e.ui.autocomplete.escapeRegex(n),"i");return e.grep(t,function(e){return r.test(e.label||e.value||e)})}}),e.widget("ui.autocomplete",e.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(e){return e+(e>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(e){var t;this._superApply(arguments);if(this.options.disabled||this.cancelSearch)return;e&&e.length?t=this.options.messages.results(e.length):t=this.options.messages.noResults,this.liveRegion.text(t)}})})(jQuery);(function(e,t){var n,r,i,s,o="ui-button ui-widget ui-state-default ui-corner-all",u="ui-state-hover ui-state-active ",a="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",f=function(){var t=e(this).find(":ui-button");setTimeout(function(){t.button("refresh")},1)},l=function(t){var n=t.name,r=t.form,i=e([]);return n&&(r?i=e(r).find("[name='"+n+"']"):i=e("[name='"+n+"']",t.ownerDocument).filter(function(){return!this.form})),i};e.widget("ui.button",{version:"1.9.2",defaultElement:"<button>",options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset"+this.eventNamespace).bind("reset"+this.eventNamespace,f),typeof this.options.disabled!="boolean"?this.options.disabled=!!this.element.prop("disabled"):this.element.prop("disabled",this.options.disabled),this._determineButtonType(),this.hasTitle=!!this.buttonElement.attr("title");var t=this,u=this.options,a=this.type==="checkbox"||this.type==="radio",c=a?"":"ui-state-active",h="ui-state-focus";u.label===null&&(u.label=this.type==="input"?this.buttonElement.val():this.buttonElement.html()),this._hoverable(this.buttonElement),this.buttonElement.addClass(o).attr("role","button").bind("mouseenter"+this.eventNamespace,function(){if(u.disabled)return;this===n&&e(this).addClass("ui-state-active")}).bind("mouseleave"+this.eventNamespace,function(){if(u.disabled)return;e(this).removeClass(c)}).bind("click"+this.eventNamespace,function(e){u.disabled&&(e.preventDefault(),e.stopImmediatePropagation())}),this.element.bind("focus"+this.eventNamespace,function(){t.buttonElement.addClass(h)}).bind("blur"+this.eventNamespace,function(){t.buttonElement.removeClass(h)}),a&&(this.element.bind("change"+this.eventNamespace,function(){if(s)return;t.refresh()}),this.buttonElement.bind("mousedown"+this.eventNamespace,function(e){if(u.disabled)return;s=!1,r=e.pageX,i=e.pageY}).bind("mouseup"+this.eventNamespace,function(e){if(u.disabled)return;if(r!==e.pageX||i!==e.pageY)s=!0})),this.type==="checkbox"?this.buttonElement.bind("click"+this.eventNamespace,function(){if(u.disabled||s)return!1;e(this).toggleClass("ui-state-active"),t.buttonElement.attr("aria-pressed",t.element[0].checked)}):this.type==="radio"?this.buttonElement.bind("click"+this.eventNamespace,function(){if(u.disabled||s)return!1;e(this).addClass("ui-state-active"),t.buttonElement.attr("aria-pressed","true");var n=t.element[0];l(n).not(n).map(function(){return e(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")}):(this.buttonElement.bind("mousedown"+this.eventNamespace,function(){if(u.disabled)return!1;e(this).addClass("ui-state-active"),n=this,t.document.one("mouseup",function(){n=null})}).bind("mouseup"+this.eventNamespace,function(){if(u.disabled)return!1;e(this).removeClass("ui-state-active")}).bind("keydown"+this.eventNamespace,function(t){if(u.disabled)return!1;(t.keyCode===e.ui.keyCode.SPACE||t.keyCode===e.ui.keyCode.ENTER)&&e(this).addClass("ui-state-active")}).bind("keyup"+this.eventNamespace,function(){e(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(t){t.keyCode===e.ui.keyCode.SPACE&&e(this).click()})),this._setOption("disabled",u.disabled),this._resetButton()},_determineButtonType:function(){var e,t,n;this.element.is("[type=checkbox]")?this.type="checkbox":this.element.is("[type=radio]")?this.type="radio":this.element.is("input")?this.type="input":this.type="button",this.type==="checkbox"||this.type==="radio"?(e=this.element.parents().last(),t="label[for='"+this.element.attr("id")+"']",this.buttonElement=e.find(t),this.buttonElement.length||(e=e.length?e.siblings():this.element.siblings(),this.buttonElement=e.filter(t),this.buttonElement.length||(this.buttonElement=e.find(t))),this.element.addClass("ui-helper-hidden-accessible"),n=this.element.is(":checked"),n&&this.buttonElement.addClass("ui-state-active"),this.buttonElement.prop("aria-pressed",n)):this.buttonElement=this.element},widget:function(){return this.buttonElement},_destroy:function(){this.element.removeClass("ui-helper-hidden-accessible"),this.buttonElement.removeClass(o+" "+u+" "+a).removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html()),this.hasTitle||this.buttonElement.removeAttr("title")},_setOption:function(e,t){this._super(e,t);if(e==="disabled"){t?this.element.prop("disabled",!0):this.element.prop("disabled",!1);return}this._resetButton()},refresh:function(){var t=this.element.is("input, button")?this.element.is(":disabled"):this.element.hasClass("ui-button-disabled");t!==this.options.disabled&&this._setOption("disabled",t),this.type==="radio"?l(this.element[0]).each(function(){e(this).is(":checked")?e(this).button("widget").addClass("ui-state-active").attr("aria-pressed","true"):e(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")}):this.type==="checkbox"&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false"))},_resetButton:function(){if(this.type==="input"){this.options.label&&this.element.val(this.options.label);return}var t=this.buttonElement.removeClass(a),n=e("<span></span>",this.document[0]).addClass("ui-button-text").html(this.options.label).appendTo(t.empty()).text(),r=this.options.icons,i=r.primary&&r.secondary,s=[];r.primary||r.secondary?(this.options.text&&s.push("ui-button-text-icon"+(i?"s":r.primary?"-primary":"-secondary")),r.primary&&t.prepend("<span class='ui-button-icon-primary ui-icon "+r.primary+"'></span>"),r.secondary&&t.append("<span class='ui-button-icon-secondary ui-icon "+r.secondary+"'></span>"),this.options.text||(s.push(i?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||t.attr("title",e.trim(n)))):s.push("ui-button-text-only"),t.addClass(s.join(" "))}}),e.widget("ui.buttonset",{version:"1.9.2",options:{items:"button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(e,t){e==="disabled"&&this.buttons.button("option",e,t),this._super(e,t)},refresh:function(){var t=this.element.css("direction")==="rtl";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return e(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(t?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(t?"ui-corner-left":"ui-corner-right").end().end()},_destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return e(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy")}})})(jQuery);(function($,undefined){function Datepicker(){this.debug=!1,this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},$.extend(this._defaults,this.regional[""]),this.dpDiv=bindHover($('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}function bindHover(e){var t="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return e.delegate(t,"mouseout",function(){$(this).removeClass("ui-state-hover"),this.className.indexOf("ui-datepicker-prev")!=-1&&$(this).removeClass("ui-datepicker-prev-hover"),this.className.indexOf("ui-datepicker-next")!=-1&&$(this).removeClass("ui-datepicker-next-hover")}).delegate(t,"mouseover",function(){$.datepicker._isDisabledDatepicker(instActive.inline?e.parent()[0]:instActive.input[0])||($(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),$(this).addClass("ui-state-hover"),this.className.indexOf("ui-datepicker-prev")!=-1&&$(this).addClass("ui-datepicker-prev-hover"),this.className.indexOf("ui-datepicker-next")!=-1&&$(this).addClass("ui-datepicker-next-hover"))})}function extendRemove(e,t){$.extend(e,t);for(var n in t)if(t[n]==null||t[n]==undefined)e[n]=t[n];return e}$.extend($.ui,{datepicker:{version:"1.9.2"}});var PROP_NAME="datepicker",dpuuid=(new Date).getTime(),instActive;$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(e){return extendRemove(this._defaults,e||{}),this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(var attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase(),inline=nodeName=="div"||nodeName=="span";target.id||(this.uuid+=1,target.id="dp"+this.uuid);var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{}),nodeName=="input"?this._connectDatepicker(target,inst):inline&&this._inlineDatepicker(target,inst)},_newInst:function(e,t){var n=e[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1");return{id:n,input:e,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:t,dpDiv:t?bindHover($('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')):this.dpDiv}},_connectDatepicker:function(e,t){var n=$(e);t.append=$([]),t.trigger=$([]);if(n.hasClass(this.markerClassName))return;this._attachments(n,t),n.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(e,n,r){t.settings[n]=r}).bind("getData.datepicker",function(e,n){return this._get(t,n)}),this._autoSize(t),$.data(e,PROP_NAME,t),t.settings.disabled&&this._disableDatepicker(e)},_attachments:function(e,t){var n=this._get(t,"appendText"),r=this._get(t,"isRTL");t.append&&t.append.remove(),n&&(t.append=$('<span class="'+this._appendClass+'">'+n+"</span>"),e[r?"before":"after"](t.append)),e.unbind("focus",this._showDatepicker),t.trigger&&t.trigger.remove();var i=this._get(t,"showOn");(i=="focus"||i=="both")&&e.focus(this._showDatepicker);if(i=="button"||i=="both"){var s=this._get(t,"buttonText"),o=this._get(t,"buttonImage");t.trigger=$(this._get(t,"buttonImageOnly")?$("<img/>").addClass(this._triggerClass).attr({src:o,alt:s,title:s}):$('<button type="button"></button>').addClass(this._triggerClass).html(o==""?s:$("<img/>").attr({src:o,alt:s,title:s}))),e[r?"before":"after"](t.trigger),t.trigger.click(function(){return $.datepicker._datepickerShowing&&$.datepicker._lastInput==e[0]?$.datepicker._hideDatepicker():$.datepicker._datepickerShowing&&$.datepicker._lastInput!=e[0]?($.datepicker._hideDatepicker(),$.datepicker._showDatepicker(e[0])):$.datepicker._showDatepicker(e[0]),!1})}},_autoSize:function(e){if(this._get(e,"autoSize")&&!e.inline){var t=new Date(2009,11,20),n=this._get(e,"dateFormat");if(n.match(/[DM]/)){var r=function(e){var t=0,n=0;for(var r=0;r<e.length;r++)e[r].length>t&&(t=e[r].length,n=r);return n};t.setMonth(r(this._get(e,n.match(/MM/)?"monthNames":"monthNamesShort"))),t.setDate(r(this._get(e,n.match(/DD/)?"dayNames":"dayNamesShort"))+20-t.getDay())}e.input.attr("size",this._formatDate(e,t).length)}},_inlineDatepicker:function(e,t){var n=$(e);if(n.hasClass(this.markerClassName))return;n.addClass(this.markerClassName).append(t.dpDiv).bind("setData.datepicker",function(e,n,r){t.settings[n]=r}).bind("getData.datepicker",function(e,n){return this._get(t,n)}),$.data(e,PROP_NAME,t),this._setDate(t,this._getDefaultDate(t),!0),this._updateDatepicker(t),this._updateAlternate(t),t.settings.disabled&&this._disableDatepicker(e),t.dpDiv.css("display","block")},_dialogDatepicker:function(e,t,n,r,i){var s=this._dialogInst;if(!s){this.uuid+=1;var o="dp"+this.uuid;this._dialogInput=$('<input type="text" id="'+o+'" style="position: absolute; top: -100px; width: 0px;"/>'),this._dialogInput.keydown(this._doKeyDown),$("body").append(this._dialogInput),s=this._dialogInst=this._newInst(this._dialogInput,!1),s.settings={},$.data(this._dialogInput[0],PROP_NAME,s)}extendRemove(s.settings,r||{}),t=t&&t.constructor==Date?this._formatDate(s,t):t,this._dialogInput.val(t),this._pos=i?i.length?i:[i.pageX,i.pageY]:null;if(!this._pos){var u=document.documentElement.clientWidth,a=document.documentElement.clientHeight,f=document.documentElement.scrollLeft||document.body.scrollLeft,l=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[u/2-100+f,a/2-150+l]}return this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),s.settings.onSelect=n,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),$.blockUI&&$.blockUI(this.dpDiv),$.data(this._dialogInput[0],PROP_NAME,s),this},_destroyDatepicker:function(e){var t=$(e),n=$.data(e,PROP_NAME);if(!t.hasClass(this.markerClassName))return;var r=e.nodeName.toLowerCase();$.removeData(e,PROP_NAME),r=="input"?(n.append.remove(),n.trigger.remove(),t.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):(r=="div"||r=="span")&&t.removeClass(this.markerClassName).empty()},_enableDatepicker:function(e){var t=$(e),n=$.data(e,PROP_NAME);if(!t.hasClass(this.markerClassName))return;var r=e.nodeName.toLowerCase();if(r=="input")e.disabled=!1,n.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""});else if(r=="div"||r=="span"){var i=t.children("."+this._inlineClass);i.children().removeClass("ui-state-disabled"),i.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)}this._disabledInputs=$.map(this._disabledInputs,function(t){return t==e?null:t})},_disableDatepicker:function(e){var t=$(e),n=$.data(e,PROP_NAME);if(!t.hasClass(this.markerClassName))return;var r=e.nodeName.toLowerCase();if(r=="input")e.disabled=!0,n.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"});else if(r=="div"||r=="span"){var i=t.children("."+this._inlineClass);i.children().addClass("ui-state-disabled"),i.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)}this._disabledInputs=$.map(this._disabledInputs,function(t){return t==e?null:t}),this._disabledInputs[this._disabledInputs.length]=e},_isDisabledDatepicker:function(e){if(!e)return!1;for(var t=0;t<this._disabledInputs.length;t++)if(this._disabledInputs[t]==e)return!0;return!1},_getInst:function(e){try{return $.data(e,PROP_NAME)}catch(t){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(e,t,n){var r=this._getInst(e);if(arguments.length==2&&typeof t=="string")return t=="defaults"?$.extend({},$.datepicker._defaults):r?t=="all"?$.extend({},r.settings):this._get(r,t):null;var i=t||{};typeof t=="string"&&(i={},i[t]=n);if(r){this._curInst==r&&this._hideDatepicker();var s=this._getDateDatepicker(e,!0),o=this._getMinMaxDate(r,"min"),u=this._getMinMaxDate(r,"max");extendRemove(r.settings,i),o!==null&&i.dateFormat!==undefined&&i.minDate===undefined&&(r.settings.minDate=this._formatDate(r,o)),u!==null&&i.dateFormat!==undefined&&i.maxDate===undefined&&(r.settings.maxDate=this._formatDate(r,u)),this._attachments($(e),r),this._autoSize(r),this._setDate(r,s),this._updateAlternate(r),this._updateDatepicker(r)}},_changeDatepicker:function(e,t,n){this._optionDatepicker(e,t,n)},_refreshDatepicker:function(e){var t=this._getInst(e);t&&this._updateDatepicker(t)},_setDateDatepicker:function(e,t){var n=this._getInst(e);n&&(this._setDate(n,t),this._updateDatepicker(n),this._updateAlternate(n))},_getDateDatepicker:function(e,t){var n=this._getInst(e);return n&&!n.inline&&this._setDateFromField(n,t),n?this._getDate(n):null},_doKeyDown:function(e){var t=$.datepicker._getInst(e.target),n=!0,r=t.dpDiv.is(".ui-datepicker-rtl");t._keyEvent=!0;if($.datepicker._datepickerShowing)switch(e.keyCode){case 9:$.datepicker._hideDatepicker(),n=!1;break;case 13:var i=$("td."+$.datepicker._dayOverClass+":not(."+$.datepicker._currentClass+")",t.dpDiv);i[0]&&$.datepicker._selectDay(e.target,t.selectedMonth,t.selectedYear,i[0]);var s=$.datepicker._get(t,"onSelect");if(s){var o=$.datepicker._formatDate(t);s.apply(t.input?t.input[0]:null,[o,t])}else $.datepicker._hideDatepicker();return!1;case 27:$.datepicker._hideDatepicker();break;case 33:$.datepicker._adjustDate(e.target,e.ctrlKey?-$.datepicker._get(t,"stepBigMonths"):-$.datepicker._get(t,"stepMonths"),"M");break;case 34:$.datepicker._adjustDate(e.target,e.ctrlKey?+$.datepicker._get(t,"stepBigMonths"):+$.datepicker._get(t,"stepMonths"),"M");break;case 35:(e.ctrlKey||e.metaKey)&&$.datepicker._clearDate(e.target),n=e.ctrlKey||e.metaKey;break;case 36:(e.ctrlKey||e.metaKey)&&$.datepicker._gotoToday(e.target),n=e.ctrlKey||e.metaKey;break;case 37:(e.ctrlKey||e.metaKey)&&$.datepicker._adjustDate(e.target,r?1:-1,"D"),n=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&$.datepicker._adjustDate(e.target,e.ctrlKey?-$.datepicker._get(t,"stepBigMonths"):-$.datepicker._get(t,"stepMonths"),"M");break;case 38:(e.ctrlKey||e.metaKey)&&$.datepicker._adjustDate(e.target,-7,"D"),n=e.ctrlKey||e.metaKey;break;case 39:(e.ctrlKey||e.metaKey)&&$.datepicker._adjustDate(e.target,r?-1:1,"D"),n=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&$.datepicker._adjustDate(e.target,e.ctrlKey?+$.datepicker._get(t,"stepBigMonths"):+$.datepicker._get(t,"stepMonths"),"M");break;case 40:(e.ctrlKey||e.metaKey)&&$.datepicker._adjustDate(e.target,7,"D"),n=e.ctrlKey||e.metaKey;break;default:n=!1}else e.keyCode==36&&e.ctrlKey?$.datepicker._showDatepicker(this):n=!1;n&&(e.preventDefault(),e.stopPropagation())},_doKeyPress:function(e){var t=$.datepicker._getInst(e.target);if($.datepicker._get(t,"constrainInput")){var n=$.datepicker._possibleChars($.datepicker._get(t,"dateFormat")),r=String.fromCharCode(e.charCode==undefined?e.keyCode:e.charCode);return e.ctrlKey||e.metaKey||r<" "||!n||n.indexOf(r)>-1}},_doKeyUp:function(e){var t=$.datepicker._getInst(e.target);if(t.input.val()!=t.lastVal)try{var n=$.datepicker.parseDate($.datepicker._get(t,"dateFormat"),t.input?t.input.val():null,$.datepicker._getFormatConfig(t));n&&($.datepicker._setDateFromField(t),$.datepicker._updateAlternate(t),$.datepicker._updateDatepicker(t))}catch(r){$.datepicker.log(r)}return!0},_showDatepicker:function(e){e=e.target||e,e.nodeName.toLowerCase()!="input"&&(e=$("input",e.parentNode)[0]);if($.datepicker._isDisabledDatepicker(e)||$.datepicker._lastInput==e)return;var t=$.datepicker._getInst(e);$.datepicker._curInst&&$.datepicker._curInst!=t&&($.datepicker._curInst.dpDiv.stop(!0,!0),t&&$.datepicker._datepickerShowing&&$.datepicker._hideDatepicker($.datepicker._curInst.input[0]));var n=$.datepicker._get(t,"beforeShow"),r=n?n.apply(e,[e,t]):{};if(r===!1)return;extendRemove(t.settings,r),t.lastVal=null,$.datepicker._lastInput=e,$.datepicker._setDateFromField(t),$.datepicker._inDialog&&(e.value=""),$.datepicker._pos||($.datepicker._pos=$.datepicker._findPos(e),$.datepicker._pos[1]+=e.offsetHeight);var i=!1;$(e).parents().each(function(){return i|=$(this).css("position")=="fixed",!i});var s={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null,t.dpDiv.empty(),t.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),$.datepicker._updateDatepicker(t),s=$.datepicker._checkOffset(t,s,i),t.dpDiv.css({position:$.datepicker._inDialog&&$.blockUI?"static":i?"fixed":"absolute",display:"none",left:s.left+"px",top:s.top+"px"});if(!t.inline){var o=$.datepicker._get(t,"showAnim"),u=$.datepicker._get(t,"duration"),a=function(){var e=t.dpDiv.find("iframe.ui-datepicker-cover");if(!!e.length){var n=$.datepicker._getBorders(t.dpDiv);e.css({left:-n[0],top:-n[1],width:t.dpDiv.outerWidth(),height:t.dpDiv.outerHeight()})}};t.dpDiv.zIndex($(e).zIndex()+1),$.datepicker._datepickerShowing=!0,$.effects&&($.effects.effect[o]||$.effects[o])?t.dpDiv.show(o,$.datepicker._get(t,"showOptions"),u,a):t.dpDiv[o||"show"](o?u:null,a),(!o||!u)&&a(),t.input.is(":visible")&&!t.input.is(":disabled")&&t.input.focus(),$.datepicker._curInst=t}},_updateDatepicker:function(e){this.maxRows=4;var t=$.datepicker._getBorders(e.dpDiv);instActive=e,e.dpDiv.empty().append(this._generateHTML(e)),this._attachHandlers(e);var n=e.dpDiv.find("iframe.ui-datepicker-cover");!n.length||n.css({left:-t[0],top:-t[1],width:e.dpDiv.outerWidth(),height:e.dpDiv.outerHeight()}),e.dpDiv.find("."+this._dayOverClass+" a").mouseover();var r=this._getNumberOfMonths(e),i=r[1],s=17;e.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),i>1&&e.dpDiv.addClass("ui-datepicker-multi-"+i).css("width",s*i+"em"),e.dpDiv[(r[0]!=1||r[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi"),e.dpDiv[(this._get(e,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),e==$.datepicker._curInst&&$.datepicker._datepickerShowing&&e.input&&e.input.is(":visible")&&!e.input.is(":disabled")&&e.input[0]!=document.activeElement&&e.input.focus();if(e.yearshtml){var o=e.yearshtml;setTimeout(function(){o===e.yearshtml&&e.yearshtml&&e.dpDiv.find("select.ui-datepicker-year:first").replaceWith(e.yearshtml),o=e.yearshtml=null},0)}},_getBorders:function(e){var t=function(e){return{thin:1,medium:2,thick:3}[e]||e};return[parseFloat(t(e.css("border-left-width"))),parseFloat(t(e.css("border-top-width")))]},_checkOffset:function(e,t,n){var r=e.dpDiv.outerWidth(),i=e.dpDiv.outerHeight(),s=e.input?e.input.outerWidth():0,o=e.input?e.input.outerHeight():0,u=document.documentElement.clientWidth+(n?0:$(document).scrollLeft()),a=document.documentElement.clientHeight+(n?0:$(document).scrollTop());return t.left-=this._get(e,"isRTL")?r-s:0,t.left-=n&&t.left==e.input.offset().left?$(document).scrollLeft():0,t.top-=n&&t.top==e.input.offset().top+o?$(document).scrollTop():0,t.left-=Math.min(t.left,t.left+r>u&&u>r?Math.abs(t.left+r-u):0),t.top-=Math.min(t.top,t.top+i>a&&a>i?Math.abs(i+o):0),t},_findPos:function(e){var t=this._getInst(e),n=this._get(t,"isRTL");while(e&&(e.type=="hidden"||e.nodeType!=1||$.expr.filters.hidden(e)))e=e[n?"previousSibling":"nextSibling"];var r=$(e).offset();return[r.left,r.top]},_hideDatepicker:function(e){var t=this._curInst;if(!t||e&&t!=$.data(e,PROP_NAME))return;if(this._datepickerShowing){var n=this._get(t,"showAnim"),r=this._get(t,"duration"),i=function(){$.datepicker._tidyDialog(t)};$.effects&&($.effects.effect[n]||$.effects[n])?t.dpDiv.hide(n,$.datepicker._get(t,"showOptions"),r,i):t.dpDiv[n=="slideDown"?"slideUp":n=="fadeIn"?"fadeOut":"hide"](n?r:null,i),n||i(),this._datepickerShowing=!1;var s=this._get(t,"onClose");s&&s.apply(t.input?t.input[0]:null,[t.input?t.input.val():"",t]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),$.blockUI&&($.unblockUI(),$("body").append(this.dpDiv))),this._inDialog=!1}},_tidyDialog:function(e){e.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(e){if(!$.datepicker._curInst)return;var t=$(e.target),n=$.datepicker._getInst(t[0]);(t[0].id!=$.datepicker._mainDivId&&t.parents("#"+$.datepicker._mainDivId).length==0&&!t.hasClass($.datepicker.markerClassName)&&!t.closest("."+$.datepicker._triggerClass).length&&$.datepicker._datepickerShowing&&(!$.datepicker._inDialog||!$.blockUI)||t.hasClass($.datepicker.markerClassName)&&$.datepicker._curInst!=n)&&$.datepicker._hideDatepicker()},_adjustDate:function(e,t,n){var r=$(e),i=this._getInst(r[0]);if(this._isDisabledDatepicker(r[0]))return;this._adjustInstDate(i,t+(n=="M"?this._get(i,"showCurrentAtPos"):0),n),this._updateDatepicker(i)},_gotoToday:function(e){var t=$(e),n=this._getInst(t[0]);if(this._get(n,"gotoCurrent")&&n.currentDay)n.selectedDay=n.currentDay,n.drawMonth=n.selectedMonth=n.currentMonth,n.drawYear=n.selectedYear=n.currentYear;else{var r=new Date;n.selectedDay=r.getDate(),n.drawMonth=n.selectedMonth=r.getMonth(),n.drawYear=n.selectedYear=r.getFullYear()}this._notifyChange(n),this._adjustDate(t)},_selectMonthYear:function(e,t,n){var r=$(e),i=this._getInst(r[0]);i["selected"+(n=="M"?"Month":"Year")]=i["draw"+(n=="M"?"Month":"Year")]=parseInt(t.options[t.selectedIndex].value,10),this._notifyChange(i),this._adjustDate(r)},_selectDay:function(e,t,n,r){var i=$(e);if($(r).hasClass(this._unselectableClass)||this._isDisabledDatepicker(i[0]))return;var s=this._getInst(i[0]);s.selectedDay=s.currentDay=$("a",r).html(),s.selectedMonth=s.currentMonth=t,s.selectedYear=s.currentYear=n,this._selectDate(e,this._formatDate(s,s.currentDay,s.currentMonth,s.currentYear))},_clearDate:function(e){var t=$(e),n=this._getInst(t[0]);this._selectDate(t,"")},_selectDate:function(e,t){var n=$(e),r=this._getInst(n[0]);t=t!=null?t:this._formatDate(r),r.input&&r.input.val(t),this._updateAlternate(r);var i=this._get(r,"onSelect");i?i.apply(r.input?r.input[0]:null,[t,r]):r.input&&r.input.trigger("change"),r.inline?this._updateDatepicker(r):(this._hideDatepicker(),this._lastInput=r.input[0],typeof r.input[0]!="object"&&r.input.focus(),this._lastInput=null)},_updateAlternate:function(e){var t=this._get(e,"altField");if(t){var n=this._get(e,"altFormat")||this._get(e,"dateFormat"),r=this._getDate(e),i=this.formatDate(n,r,this._getFormatConfig(e));$(t).each(function(){$(this).val(i)})}},noWeekends:function(e){var t=e.getDay();return[t>0&&t<6,""]},iso8601Week:function(e){var t=new Date(e.getTime());t.setDate(t.getDate()+4-(t.getDay()||7));var n=t.getTime();return t.setMonth(0),t.setDate(1),Math.floor(Math.round((n-t)/864e5)/7)+1},parseDate:function(e,t,n){if(e==null||t==null)throw"Invalid arguments";t=typeof t=="object"?t.toString():t+"";if(t=="")return null;var r=(n?n.shortYearCutoff:null)||this._defaults.shortYearCutoff;r=typeof r!="string"?r:(new Date).getFullYear()%100+parseInt(r,10);var i=(n?n.dayNamesShort:null)||this._defaults.dayNamesShort,s=(n?n.dayNames:null)||this._defaults.dayNames,o=(n?n.monthNamesShort:null)||this._defaults.monthNamesShort,u=(n?n.monthNames:null)||this._defaults.monthNames,a=-1,f=-1,l=-1,c=-1,h=!1,p=function(t){var n=y+1<e.length&&e.charAt(y+1)==t;return n&&y++,n},d=function(e){var n=p(e),r=e=="@"?14:e=="!"?20:e=="y"&&n?4:e=="o"?3:2,i=new RegExp("^\\d{1,"+r+"}"),s=t.substring(g).match(i);if(!s)throw"Missing number at position "+g;return g+=s[0].length,parseInt(s[0],10)},v=function(e,n,r){var i=$.map(p(e)?r:n,function(e,t){return[[t,e]]}).sort(function(e,t){return-(e[1].length-t[1].length)}),s=-1;$.each(i,function(e,n){var r=n[1];if(t.substr(g,r.length).toLowerCase()==r.toLowerCase())return s=n[0],g+=r.length,!1});if(s!=-1)return s+1;throw"Unknown name at position "+g},m=function(){if(t.charAt(g)!=e.charAt(y))throw"Unexpected literal at position "+g;g++},g=0;for(var y=0;y<e.length;y++)if(h)e.charAt(y)=="'"&&!p("'")?h=!1:m();else switch(e.charAt(y)){case"d":l=d("d");break;case"D":v("D",i,s);break;case"o":c=d("o");break;case"m":f=d("m");break;case"M":f=v("M",o,u);break;case"y":a=d("y");break;case"@":var b=new Date(d("@"));a=b.getFullYear(),f=b.getMonth()+1,l=b.getDate();break;case"!":var b=new Date((d("!")-this._ticksTo1970)/1e4);a=b.getFullYear(),f=b.getMonth()+1,l=b.getDate();break;case"'":p("'")?m():h=!0;break;default:m()}if(g<t.length){var w=t.substr(g);if(!/^\s+/.test(w))throw"Extra/unparsed characters found in date: "+w}a==-1?a=(new Date).getFullYear():a<100&&(a+=(new Date).getFullYear()-(new Date).getFullYear()%100+(a<=r?0:-100));if(c>-1){f=1,l=c;do{var E=this._getDaysInMonth(a,f-1);if(l<=E)break;f++,l-=E}while(!0)}var b=this._daylightSavingAdjust(new Date(a,f-1,l));if(b.getFullYear()!=a||b.getMonth()+1!=f||b.getDate()!=l)throw"Invalid date";return b},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1e7,formatDate:function(e,t,n){if(!t)return"";var r=(n?n.dayNamesShort:null)||this._defaults.dayNamesShort,i=(n?n.dayNames:null)||this._defaults.dayNames,s=(n?n.monthNamesShort:null)||this._defaults.monthNamesShort,o=(n?n.monthNames:null)||this._defaults.monthNames,u=function(t){var n=h+1<e.length&&e.charAt(h+1)==t;return n&&h++,n},a=function(e,t,n){var r=""+t;if(u(e))while(r.length<n)r="0"+r;return r},f=function(e,t,n,r){return u(e)?r[t]:n[t]},l="",c=!1;if(t)for(var h=0;h<e.length;h++)if(c)e.charAt(h)=="'"&&!u("'")?c=!1:l+=e.charAt(h);else switch(e.charAt(h)){case"d":l+=a("d",t.getDate(),2);break;case"D":l+=f("D",t.getDay(),r,i);break;case"o":l+=a("o",Math.round(((new Date(t.getFullYear(),t.getMonth(),t.getDate())).getTime()-(new Date(t.getFullYear(),0,0)).getTime())/864e5),3);break;case"m":l+=a("m",t.getMonth()+1,2);break;case"M":l+=f("M",t.getMonth(),s,o);break;case"y":l+=u("y")?t.getFullYear():(t.getYear()%100<10?"0":"")+t.getYear()%100;break;case"@":l+=t.getTime();break;case"!":l+=t.getTime()*1e4+this._ticksTo1970;break;case"'":u("'")?l+="'":c=!0;break;default:l+=e.charAt(h)}return l},_possibleChars:function(e){var t="",n=!1,r=function(t){var n=i+1<e.length&&e.charAt(i+1)==t;return n&&i++,n};for(var i=0;i<e.length;i++)if(n)e.charAt(i)=="'"&&!r("'")?n=!1:t+=e.charAt(i);else switch(e.charAt(i)){case"d":case"m":case"y":case"@":t+="0123456789";break;case"D":case"M":return null;case"'":r("'")?t+="'":n=!0;break;default:t+=e.charAt(i)}return t},_get:function(e,t){return e.settings[t]!==undefined?e.settings[t]:this._defaults[t]},_setDateFromField:function(e,t){if(e.input.val()==e.lastVal)return;var n=this._get(e,"dateFormat"),r=e.lastVal=e.input?e.input.val():null,i,s;i=s=this._getDefaultDate(e);var o=this._getFormatConfig(e);try{i=this.parseDate(n,r,o)||s}catch(u){this.log(u),r=t?"":r}e.selectedDay=i.getDate(),e.drawMonth=e.selectedMonth=i.getMonth(),e.drawYear=e.selectedYear=i.getFullYear(),e.currentDay=r?i.getDate():0,e.currentMonth=r?i.getMonth():0,e.currentYear=r?i.getFullYear():0,this._adjustInstDate(e)},_getDefaultDate:function(e){return this._restrictMinMax(e,this._determineDate(e,this._get(e,"defaultDate"),new Date))},_determineDate:function(e,t,n){var r=function(e){var t=new Date;return t.setDate(t.getDate()+e),t},i=function(t){try{return $.datepicker.parseDate($.datepicker._get(e,"dateFormat"),t,$.datepicker._getFormatConfig(e))}catch(n){}var r=(t.toLowerCase().match(/^c/)?$.datepicker._getDate(e):null)||new Date,i=r.getFullYear(),s=r.getMonth(),o=r.getDate(),u=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,a=u.exec(t);while(a){switch(a[2]||"d"){case"d":case"D":o+=parseInt(a[1],10);break;case"w":case"W":o+=parseInt(a[1],10)*7;break;case"m":case"M":s+=parseInt(a[1],10),o=Math.min(o,$.datepicker._getDaysInMonth(i,s));break;case"y":case"Y":i+=parseInt(a[1],10),o=Math.min(o,$.datepicker._getDaysInMonth(i,s))}a=u.exec(t)}return new Date(i,s,o)},s=t==null||t===""?n:typeof t=="string"?i(t):typeof t=="number"?isNaN(t)?n:r(t):new Date(t.getTime());return s=s&&s.toString()=="Invalid Date"?n:s,s&&(s.setHours(0),s.setMinutes(0),s.setSeconds(0),s.setMilliseconds(0)),this._daylightSavingAdjust(s)},_daylightSavingAdjust:function(e){return e?(e.setHours(e.getHours()>12?e.getHours()+2:0),e):null},_setDate:function(e,t,n){var r=!t,i=e.selectedMonth,s=e.selectedYear,o=this._restrictMinMax(e,this._determineDate(e,t,new Date));e.selectedDay=e.currentDay=o.getDate(),e.drawMonth=e.selectedMonth=e.currentMonth=o.getMonth(),e.drawYear=e.selectedYear=e.currentYear=o.getFullYear(),(i!=e.selectedMonth||s!=e.selectedYear)&&!n&&this._notifyChange(e),this._adjustInstDate(e),e.input&&e.input.val(r?"":this._formatDate(e))},_getDate:function(e){var t=!e.currentYear||e.input&&e.input.val()==""?null:this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return t},_attachHandlers:function(e){var t=this._get(e,"stepMonths"),n="#"+e.id.replace(/\\\\/g,"\\");e.dpDiv.find("[data-handler]").map(function(){var e={prev:function(){window["DP_jQuery_"+dpuuid].datepicker._adjustDate(n,-t,"M")},next:function(){window["DP_jQuery_"+dpuuid].datepicker._adjustDate(n,+t,"M")},hide:function(){window["DP_jQuery_"+dpuuid].datepicker._hideDatepicker()},today:function(){window["DP_jQuery_"+dpuuid].datepicker._gotoToday(n)},selectDay:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectDay(n,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectMonthYear(n,this,"M"),!1},selectYear:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectMonthYear(n,this,"Y"),!1}};$(this).bind(this.getAttribute("data-event"),e[this.getAttribute("data-handler")])})},_generateHTML:function(e){var t=new Date;t=this._daylightSavingAdjust(new Date(t.getFullYear(),t.getMonth(),t.getDate()));var n=this._get(e,"isRTL"),r=this._get(e,"showButtonPanel"),i=this._get(e,"hideIfNoPrevNext"),s=this._get(e,"navigationAsDateFormat"),o=this._getNumberOfMonths(e),u=this._get(e,"showCurrentAtPos"),a=this._get(e,"stepMonths"),f=o[0]!=1||o[1]!=1,l=this._daylightSavingAdjust(e.currentDay?new Date(e.currentYear,e.currentMonth,e.currentDay):new Date(9999,9,9)),c=this._getMinMaxDate(e,"min"),h=this._getMinMaxDate(e,"max"),p=e.drawMonth-u,d=e.drawYear;p<0&&(p+=12,d--);if(h){var v=this._daylightSavingAdjust(new Date(h.getFullYear(),h.getMonth()-o[0]*o[1]+1,h.getDate()));v=c&&v<c?c:v;while(this._daylightSavingAdjust(new Date(d,p,1))>v)p--,p<0&&(p=11,d--)}e.drawMonth=p,e.drawYear=d;var m=this._get(e,"prevText");m=s?this.formatDate(m,this._daylightSavingAdjust(new Date(d,p-a,1)),this._getFormatConfig(e)):m;var g=this._canAdjustMonth(e,-1,d,p)?'<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click" title="'+m+'"><span class="ui-icon ui-icon-circle-triangle-'+(n?"e":"w")+'">'+m+"</span></a>":i?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+m+'"><span class="ui-icon ui-icon-circle-triangle-'+(n?"e":"w")+'">'+m+"</span></a>",y=this._get(e,"nextText");y=s?this.formatDate(y,this._daylightSavingAdjust(new Date(d,p+a,1)),this._getFormatConfig(e)):y;var b=this._canAdjustMonth(e,1,d,p)?'<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click" title="'+y+'"><span class="ui-icon ui-icon-circle-triangle-'+(n?"w":"e")+'">'+y+"</span></a>":i?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+y+'"><span class="ui-icon ui-icon-circle-triangle-'+(n?"w":"e")+'">'+y+"</span></a>",w=this._get(e,"currentText"),E=this._get(e,"gotoCurrent")&&e.currentDay?l:t;w=s?this.formatDate(w,E,this._getFormatConfig(e)):w;var S=e.inline?"":'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" data-handler="hide" data-event="click">'+this._get(e,"closeText")+"</button>",x=r?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(n?S:"")+(this._isInRange(e,E)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" data-handler="today" data-event="click">'+w+"</button>":"")+(n?"":S)+"</div>":"",T=parseInt(this._get(e,"firstDay"),10);T=isNaN(T)?0:T;var N=this._get(e,"showWeek"),C=this._get(e,"dayNames"),k=this._get(e,"dayNamesShort"),L=this._get(e,"dayNamesMin"),A=this._get(e,"monthNames"),O=this._get(e,"monthNamesShort"),M=this._get(e,"beforeShowDay"),_=this._get(e,"showOtherMonths"),D=this._get(e,"selectOtherMonths"),P=this._get(e,"calculateWeek")||this.iso8601Week,H=this._getDefaultDate(e),B="";for(var j=0;j<o[0];j++){var F="";this.maxRows=4;for(var I=0;I<o[1];I++){var q=this._daylightSavingAdjust(new Date(d,p,e.selectedDay)),R=" ui-corner-all",U="";if(f){U+='<div class="ui-datepicker-group';if(o[1]>1)switch(I){case 0:U+=" ui-datepicker-group-first",R=" ui-corner-"+(n?"right":"left");break;case o[1]-1:U+=" ui-datepicker-group-last",R=" ui-corner-"+(n?"left":"right");break;default:U+=" ui-datepicker-group-middle",R=""}U+='">'}U+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+R+'">'+(/all|left/.test(R)&&j==0?n?b:g:"")+(/all|right/.test(R)&&j==0?n?g:b:"")+this._generateMonthYearHeader(e,p,d,c,h,j>0||I>0,A,O)+'</div><table class="ui-datepicker-calendar"><thead>'+"<tr>";var z=N?'<th class="ui-datepicker-week-col">'+this._get(e,"weekHeader")+"</th>":"";for(var W=0;W<7;W++){var X=(W+T)%7;z+="<th"+((W+T+6)%7>=5?' class="ui-datepicker-week-end"':"")+">"+'<span title="'+C[X]+'">'+L[X]+"</span></th>"}U+=z+"</tr></thead><tbody>";var V=this._getDaysInMonth(d,p);d==e.selectedYear&&p==e.selectedMonth&&(e.selectedDay=Math.min(e.selectedDay,V));var J=(this._getFirstDayOfMonth(d,p)-T+7)%7,K=Math.ceil((J+V)/7),Q=f?this.maxRows>K?this.maxRows:K:K;this.maxRows=Q;var G=this._daylightSavingAdjust(new Date(d,p,1-J));for(var Y=0;Y<Q;Y++){U+="<tr>";var Z=N?'<td class="ui-datepicker-week-col">'+this._get(e,"calculateWeek")(G)+"</td>":"";for(var W=0;W<7;W++){var et=M?M.apply(e.input?e.input[0]:null,[G]):[!0,""],tt=G.getMonth()!=p,nt=tt&&!D||!et[0]||c&&G<c||h&&G>h;Z+='<td class="'+((W+T+6)%7>=5?" ui-datepicker-week-end":"")+(tt?" ui-datepicker-other-month":"")+(G.getTime()==q.getTime()&&p==e.selectedMonth&&e._keyEvent||H.getTime()==G.getTime()&&H.getTime()==q.getTime()?" "+this._dayOverClass:"")+(nt?" "+this._unselectableClass+" ui-state-disabled":"")+(tt&&!_?"":" "+et[1]+(G.getTime()==l.getTime()?" "+this._currentClass:"")+(G.getTime()==t.getTime()?" ui-datepicker-today":""))+'"'+((!tt||_)&&et[2]?' title="'+et[2]+'"':"")+(nt?"":' data-handler="selectDay" data-event="click" data-month="'+G.getMonth()+'" data-year="'+G.getFullYear()+'"')+">"+(tt&&!_?" ":nt?'<span class="ui-state-default">'+G.getDate()+"</span>":'<a class="ui-state-default'+(G.getTime()==t.getTime()?" ui-state-highlight":"")+(G.getTime()==l.getTime()?" ui-state-active":"")+(tt?" ui-priority-secondary":"")+'" href="#">'+G.getDate()+"</a>")+"</td>",G.setDate(G.getDate()+1),G=this._daylightSavingAdjust(G)}U+=Z+"</tr>"}p++,p>11&&(p=0,d++),U+="</tbody></table>"+(f?"</div>"+(o[0]>0&&I==o[1]-1?'<div class="ui-datepicker-row-break"></div>':""):""),F+=U}B+=F}return B+=x+($.ui.ie6&&!e.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':""),e._keyEvent=!1,B},_generateMonthYearHeader:function(e,t,n,r,i,s,o,u){var a=this._get(e,"changeMonth"),f=this._get(e,"changeYear"),l=this._get(e,"showMonthAfterYear"),c='<div class="ui-datepicker-title">',h="";if(s||!a)h+='<span class="ui-datepicker-month">'+o[t]+"</span>";else{var p=r&&r.getFullYear()==n,d=i&&i.getFullYear()==n;h+='<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">';for(var v=0;v<12;v++)(!p||v>=r.getMonth())&&(!d||v<=i.getMonth())&&(h+='<option value="'+v+'"'+(v==t?' selected="selected"':"")+">"+u[v]+"</option>");h+="</select>"}l||(c+=h+(s||!a||!f?" ":""));if(!e.yearshtml){e.yearshtml="";if(s||!f)c+='<span class="ui-datepicker-year">'+n+"</span>";else{var m=this._get(e,"yearRange").split(":"),g=(new Date).getFullYear(),y=function(e){var t=e.match(/c[+-].*/)?n+parseInt(e.substring(1),10):e.match(/[+-].*/)?g+parseInt(e,10):parseInt(e,10);return isNaN(t)?g:t},b=y(m[0]),w=Math.max(b,y(m[1]||""));b=r?Math.max(b,r.getFullYear()):b,w=i?Math.min(w,i.getFullYear()):w,e.yearshtml+='<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">';for(;b<=w;b++)e.yearshtml+='<option value="'+b+'"'+(b==n?' selected="selected"':"")+">"+b+"</option>";e.yearshtml+="</select>",c+=e.yearshtml,e.yearshtml=null}}return c+=this._get(e,"yearSuffix"),l&&(c+=(s||!a||!f?" ":"")+h),c+="</div>",c},_adjustInstDate:function(e,t,n){var r=e.drawYear+(n=="Y"?t:0),i=e.drawMonth+(n=="M"?t:0),s=Math.min(e.selectedDay,this._getDaysInMonth(r,i))+(n=="D"?t:0),o=this._restrictMinMax(e,this._daylightSavingAdjust(new Date(r,i,s)));e.selectedDay=o.getDate(),e.drawMonth=e.selectedMonth=o.getMonth(),e.drawYear=e.selectedYear=o.getFullYear(),(n=="M"||n=="Y")&&this._notifyChange(e)},_restrictMinMax:function(e,t){var n=this._getMinMaxDate(e,"min"),r=this._getMinMaxDate(e,"max"),i=n&&t<n?n:t;return i=r&&i>r?r:i,i},_notifyChange:function(e){var t=this._get(e,"onChangeMonthYear");t&&t.apply(e.input?e.input[0]:null,[e.selectedYear,e.selectedMonth+1,e])},_getNumberOfMonths:function(e){var t=this._get(e,"numberOfMonths");return t==null?[1,1]:typeof t=="number"?[1,t]:t},_getMinMaxDate:function(e,t){return this._determineDate(e,this._get(e,t+"Date"),null)},_getDaysInMonth:function(e,t){return 32-this._daylightSavingAdjust(new Date(e,t,32)).getDate()},_getFirstDayOfMonth:function(e,t){return(new Date(e,t,1)).getDay()},_canAdjustMonth:function(e,t,n,r){var i=this._getNumberOfMonths(e),s=this._daylightSavingAdjust(new Date(n,r+(t<0?t:i[0]*i[1]),1));return t<0&&s.setDate(this._getDaysInMonth(s.getFullYear(),s.getMonth())),this._isInRange(e,s)},_isInRange:function(e,t){var n=this._getMinMaxDate(e,"min"),r=this._getMinMaxDate(e,"max");return(!n||t.getTime()>=n.getTime())&&(!r||t.getTime()<=r.getTime())},_getFormatConfig:function(e){var t=this._get(e,"shortYearCutoff");return t=typeof t!="string"?t:(new Date).getFullYear()%100+parseInt(t,10),{shortYearCutoff:t,dayNamesShort:this._get(e,"dayNamesShort"),dayNames:this._get(e,"dayNames"),monthNamesShort:this._get(e,"monthNamesShort"),monthNames:this._get(e,"monthNames")}},_formatDate:function(e,t,n,r){t||(e.currentDay=e.selectedDay,e.currentMonth=e.selectedMonth,e.currentYear=e.selectedYear);var i=t?typeof t=="object"?t:this._daylightSavingAdjust(new Date(r,n,t)):this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return this.formatDate(this._get(e,"dateFormat"),i,this._getFormatConfig(e))}}),$.fn.datepicker=function(e){if(!this.length)return this;$.datepicker.initialized||($(document).mousedown($.datepicker._checkExternalClick).find(document.body).append($.datepicker.dpDiv),$.datepicker.initialized=!0);var t=Array.prototype.slice.call(arguments,1);return typeof e!="string"||e!="isDisabled"&&e!="getDate"&&e!="widget"?e=="option"&&arguments.length==2&&typeof arguments[1]=="string"?$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this[0]].concat(t)):this.each(function(){typeof e=="string"?$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this].concat(t)):$.datepicker._attachDatepicker(this,e)}):$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this[0]].concat(t))},$.datepicker=new Datepicker,$.datepicker.initialized=!1,$.datepicker.uuid=(new Date).getTime(),$.datepicker.version="1.9.2",window["DP_jQuery_"+dpuuid]=$})(jQuery);(function(e,t){var n="ui-dialog ui-widget ui-widget-content ui-corner-all ",r={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},i={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0};e.widget("ui.dialog",{version:"1.9.2",options:{autoOpen:!0,buttons:{},closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:!1,maxWidth:!1,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(t){var n=e(this).css(t).offset().top;n<0&&e(this).css("top",t.top-n)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1e3},_create:function(){this.originalTitle=this.element.attr("title"),typeof this.originalTitle!="string"&&(this.originalTitle=""),this.oldPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.options.title=this.options.title||this.originalTitle;var t=this,r=this.options,i=r.title||" ",s,o,u,a,f;s=(this.uiDialog=e("<div>")).addClass(n+r.dialogClass).css({display:"none",outline:0,zIndex:r.zIndex}).attr("tabIndex",-1).keydown(function(n){r.closeOnEscape&&!n.isDefaultPrevented()&&n.keyCode&&n.keyCode===e.ui.keyCode.ESCAPE&&(t.close(n),n.preventDefault())}).mousedown(function(e){t.moveToTop(!1,e)}).appendTo("body"),this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(s),o=(this.uiDialogTitlebar=e("<div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").bind("mousedown",function(){s.focus()}).prependTo(s),u=e("<a href='#'></a>").addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").click(function(e){e.preventDefault(),t.close(e)}).appendTo(o),(this.uiDialogTitlebarCloseText=e("<span>")).addClass("ui-icon ui-icon-closethick").text(r.closeText).appendTo(u),a=e("<span>").uniqueId().addClass("ui-dialog-title").html(i).prependTo(o),f=(this.uiDialogButtonPane=e("<div>")).addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),(this.uiButtonSet=e("<div>")).addClass("ui-dialog-buttonset").appendTo(f),s.attr({role:"dialog","aria-labelledby":a.attr("id")}),o.find("*").add(o).disableSelection(),this._hoverable(u),this._focusable(u),r.draggable&&e.fn.draggable&&this._makeDraggable(),r.resizable&&e.fn.resizable&&this._makeResizable(),this._createButtons(r.buttons),this._isOpen=!1,e.fn.bgiframe&&s.bgiframe(),this._on(s,{keydown:function(t){if(!r.modal||t.keyCode!==e.ui.keyCode.TAB)return;var n=e(":tabbable",s),i=n.filter(":first"),o=n.filter(":last");if(t.target===o[0]&&!t.shiftKey)return i.focus(1),!1;if(t.target===i[0]&&t.shiftKey)return o.focus(1),!1}})},_init:function(){this.options.autoOpen&&this.open()},_destroy:function(){var e,t=this.oldPosition;this.overlay&&this.overlay.destroy(),this.uiDialog.hide(),this.element.removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"),this.uiDialog.remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),e=t.parent.children().eq(t.index),e.length&&e[0]!==this.element[0]?e.before(this.element):t.parent.append(this.element)},widget:function(){return this.uiDialog},close:function(t){var n=this,r,i;if(!this._isOpen)return;if(!1===this._trigger("beforeClose",t))return;return this._isOpen=!1,this.overlay&&this.overlay.destroy(),this.options.hide?this._hide(this.uiDialog,this.options.hide,function(){n._trigger("close",t)}):(this.uiDialog.hide(),this._trigger("close",t)),e.ui.dialog.overlay.resize(),this.options.modal&&(r=0,e(".ui-dialog").each(function(){this!==n.uiDialog[0]&&(i=e(this).css("z-index"),isNaN(i)||(r=Math.max(r,i)))}),e.ui.dialog.maxZ=r),this},isOpen:function(){return this._isOpen},moveToTop:function(t,n){var r=this.options,i;return r.modal&&!t||!r.stack&&!r.modal?this._trigger("focus",n):(r.zIndex>e.ui.dialog.maxZ&&(e.ui.dialog.maxZ=r.zIndex),this.overlay&&(e.ui.dialog.maxZ+=1,e.ui.dialog.overlay.maxZ=e.ui.dialog.maxZ,this.overlay.$el.css("z-index",e.ui.dialog.overlay.maxZ)),i={scrollTop:this.element.scrollTop(),scrollLeft:this.element.scrollLeft()},e.ui.dialog.maxZ+=1,this.uiDialog.css("z-index",e.ui.dialog.maxZ),this.element.attr(i),this._trigger("focus",n),this)},open:function(){if(this._isOpen)return;var t,n=this.options,r=this.uiDialog;return this._size(),this._position(n.position),r.show(n.show),this.overlay=n.modal?new e.ui.dialog.overlay(this):null,this.moveToTop(!0),t=this.element.find(":tabbable"),t.length||(t=this.uiDialogButtonPane.find(":tabbable"),t.length||(t=r)),t.eq(0).focus(),this._isOpen=!0,this._trigger("open"),this},_createButtons:function(t){var n=this,r=!1;this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),typeof t=="object"&&t!==null&&e.each(t,function(){return!(r=!0)}),r?(e.each(t,function(t,r){var i,s;r=e.isFunction(r)?{click:r,text:t}:r,r=e.extend({type:"button"},r),s=r.click,r.click=function(){s.apply(n.element[0],arguments)},i=e("<button></button>",r).appendTo(n.uiButtonSet),e.fn.button&&i.button()}),this.uiDialog.addClass("ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog)):this.uiDialog.removeClass("ui-dialog-buttons")},_makeDraggable:function(){function r(e){return{position:e.position,offset:e.offset}}var t=this,n=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(n,i){e(this).addClass("ui-dialog-dragging"),t._trigger("dragStart",n,r(i))},drag:function(e,n){t._trigger("drag",e,r(n))},stop:function(i,s){n.position=[s.position.left-t.document.scrollLeft(),s.position.top-t.document.scrollTop()],e(this).removeClass("ui-dialog-dragging"),t._trigger("dragStop",i,r(s)),e.ui.dialog.overlay.resize()}})},_makeResizable:function(n){function u(e){return{originalPosition:e.originalPosition,originalSize:e.originalSize,position:e.position,size:e.size}}n=n===t?this.options.resizable:n;var r=this,i=this.options,s=this.uiDialog.css("position"),o=typeof n=="string"?n:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:i.maxWidth,maxHeight:i.maxHeight,minWidth:i.minWidth,minHeight:this._minHeight(),handles:o,start:function(t,n){e(this).addClass("ui-dialog-resizing"),r._trigger("resizeStart",t,u(n))},resize:function(e,t){r._trigger("resize",e,u(t))},stop:function(t,n){e(this).removeClass("ui-dialog-resizing"),i.height=e(this).height(),i.width=e(this).width(),r._trigger("resizeStop",t,u(n)),e.ui.dialog.overlay.resize()}}).css("position",s).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var e=this.options;return e.height==="auto"?e.minHeight:Math.min(e.minHeight,e.height)},_position:function(t){var n=[],r=[0,0],i;if(t){if(typeof t=="string"||typeof t=="object"&&"0"in t)n=t.split?t.split(" "):[t[0],t[1]],n.length===1&&(n[1]=n[0]),e.each(["left","top"],function(e,t){+n[e]===n[e]&&(r[e]=n[e],n[e]=t)}),t={my:n[0]+(r[0]<0?r[0]:"+"+r[0])+" "+n[1]+(r[1]<0?r[1]:"+"+r[1]),at:n.join(" ")};t=e.extend({},e.ui.dialog.prototype.options.position,t)}else t=e.ui.dialog.prototype.options.position;i=this.uiDialog.is(":visible"),i||this.uiDialog.show(),this.uiDialog.position(t),i||this.uiDialog.hide()},_setOptions:function(t){var n=this,s={},o=!1;e.each(t,function(e,t){n._setOption(e,t),e in r&&(o=!0),e in i&&(s[e]=t)}),o&&this._size(),this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",s)},_setOption:function(t,r){var i,s,o=this.uiDialog;switch(t){case"buttons":this._createButtons(r);break;case"closeText":this.uiDialogTitlebarCloseText.text(""+r);break;case"dialogClass":o.removeClass(this.options.dialogClass).addClass(n+r);break;case"disabled":r?o.addClass("ui-dialog-disabled"):o.removeClass("ui-dialog-disabled");break;case"draggable":i=o.is(":data(draggable)"),i&&!r&&o.draggable("destroy"),!i&&r&&this._makeDraggable();break;case"position":this._position(r);break;case"resizable":s=o.is(":data(resizable)"),s&&!r&&o.resizable("destroy"),s&&typeof r=="string"&&o.resizable("option","handles",r),!s&&r!==!1&&this._makeResizable(r);break;case"title":e(".ui-dialog-title",this.uiDialogTitlebar).html(""+(r||" "))}this._super(t,r)},_size:function(){var t,n,r,i=this.options,s=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0}),i.minWidth>i.width&&(i.width=i.minWidth),t=this.uiDialog.css({height:"auto",width:i.width}).outerHeight(),n=Math.max(0,i.minHeight-t),i.height==="auto"?e.support.minHeight?this.element.css({minHeight:n,height:"auto"}):(this.uiDialog.show(),r=this.element.css("height","auto").height(),s||this.uiDialog.hide(),this.element.height(Math.max(r,n))):this.element.height(Math.max(i.height-t,0)),this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}}),e.extend(e.ui.dialog,{uuid:0,maxZ:0,getTitleId:function(e){var t=e.attr("id");return t||(this.uuid+=1,t=this.uuid),"ui-dialog-title-"+t},overlay:function(t){this.$el=e.ui.dialog.overlay.create(t)}}),e.extend(e.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:e.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(e){return e+".dialog-overlay"}).join(" "),create:function(t){this.instances.length===0&&(setTimeout(function(){e.ui.dialog.overlay.instances.length&&e(document).bind(e.ui.dialog.overlay.events,function(t){if(e(t.target).zIndex()<e.ui.dialog.overlay.maxZ)return!1})},1),e(window).bind("resize.dialog-overlay",e.ui.dialog.overlay.resize));var n=this.oldInstances.pop()||e("<div>").addClass("ui-widget-overlay");return e(document).bind("keydown.dialog-overlay",function(r){var i=e.ui.dialog.overlay.instances;i.length!==0&&i[i.length-1]===n&&t.options.closeOnEscape&&!r.isDefaultPrevented()&&r.keyCode&&r.keyCode===e.ui.keyCode.ESCAPE&&(t.close(r),r.preventDefault())}),n.appendTo(document.body).css({width:this.width(),height:this.height()}),e.fn.bgiframe&&n.bgiframe(),this.instances.push(n),n},destroy:function(t){var n=e.inArray(t,this.instances),r=0;n!==-1&&this.oldInstances.push(this.instances.splice(n,1)[0]),this.instances.length===0&&e([document,window]).unbind(".dialog-overlay"),t.height(0).width(0).remove(),e.each(this.instances,function(){r=Math.max(r,this.css("z-index"))}),this.maxZ=r},height:function(){var t,n;return e.ui.ie?(t=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),n=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight),t<n?e(window).height()+"px":t+"px"):e(document).height()+"px"},width:function(){var t,n;return e.ui.ie?(t=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth),n=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth),t<n?e(window).width()+"px":t+"px"):e(document).width()+"px"},resize:function(){var t=e([]);e.each(e.ui.dialog.overlay.instances,function(){t=t.add(this)}),t.css({width:0,height:0}).css({width:e.ui.dialog.overlay.width(),height:e.ui.dialog.overlay.height()})}}),e.extend(e.ui.dialog.overlay.prototype,{destroy:function(){e.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);(function(e,t){e.widget("ui.draggable",e.ui.mouse,{version:"1.9.2",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1},_create:function(){this.options.helper=="original"&&!/^(?:r|a|f)/.test(this.element.css("position"))&&(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},_destroy:function(){this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy()},_mouseCapture:function(t){var n=this.options;return this.helper||n.disabled||e(t.target).is(".ui-resizable-handle")?!1:(this.handle=this._getHandle(t),this.handle?(e(n.iframeFix===!0?"iframe":n.iframeFix).each(function(){e('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(e(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(t){var n=this.options;return this.helper=this._createHelper(t),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),e.ui.ddmanager&&(e.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,n.cursorAt&&this._adjustOffsetFromHelper(n.cursorAt),n.containment&&this._setContainment(),this._trigger("start",t)===!1?(this._clear(),!1):(this._cacheHelperProportions(),e.ui.ddmanager&&!n.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this._mouseDrag(t,!0),e.ui.ddmanager&&e.ui.ddmanager.dragStart(this,t),!0)},_mouseDrag:function(t,n){this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute");if(!n){var r=this._uiHash();if(this._trigger("drag",t,r)===!1)return this._mouseUp({}),!1;this.position=r.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";return e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var n=!1;e.ui.ddmanager&&!this.options.dropBehaviour&&(n=e.ui.ddmanager.drop(this,t)),this.dropped&&(n=this.dropped,this.dropped=!1);var r=this.element[0],i=!1;while(r&&(r=r.parentNode))r==document&&(i=!0);if(!i&&this.options.helper==="original")return!1;if(this.options.revert=="invalid"&&!n||this.options.revert=="valid"&&n||this.options.revert===!0||e.isFunction(this.options.revert)&&this.options.revert.call(this.element,n)){var s=this;e(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){s._trigger("stop",t)!==!1&&s._clear()})}else this._trigger("stop",t)!==!1&&this._clear();return!1},_mouseUp:function(t){return e("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),e.ui.ddmanager&&e.ui.ddmanager.dragStop(this,t),e.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(t){var n=!this.options.handle||!e(this.options.handle,this.element).length?!0:!1;return e(this.options.handle,this.element).find("*").andSelf().each(function(){this==t.target&&(n=!0)}),n},_createHelper:function(t){var n=this.options,r=e.isFunction(n.helper)?e(n.helper.apply(this.element[0],[t])):n.helper=="clone"?this.element.clone().removeAttr("id"):this.element;return r.parents("body").length||r.appendTo(n.appendTo=="parent"?this.element[0].parentNode:n.appendTo),r[0]!=this.element[0]&&!/(fixed|absolute)/.test(r.css("position"))&&r.css("position","absolute"),r},_adjustOffsetFromHelper:function(t){typeof t=="string"&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&e.ui.ie)t={top:0,left:0};return{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var e=this.element.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t=this.options;t.containment=="parent"&&(t.containment=this.helper[0].parentNode);if(t.containment=="document"||t.containment=="window")this.containment=[t.containment=="document"?0:e(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t.containment=="document"?0:e(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,(t.containment=="document"?0:e(window).scrollLeft())+e(t.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(t.containment=="document"?0:e(window).scrollTop())+(e(t.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(t.containment)&&t.containment.constructor!=Array){var n=e(t.containment),r=n[0];if(!r)return;var i=n.offset(),s=e(r).css("overflow")!="hidden";this.containment=[(parseInt(e(r).css("borderLeftWidth"),10)||0)+(parseInt(e(r).css("paddingLeft"),10)||0),(parseInt(e(r).css("borderTopWidth"),10)||0)+(parseInt(e(r).css("paddingTop"),10)||0),(s?Math.max(r.scrollWidth,r.offsetWidth):r.offsetWidth)-(parseInt(e(r).css("borderLeftWidth"),10)||0)-(parseInt(e(r).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(s?Math.max(r.scrollHeight,r.offsetHeight):r.offsetHeight)-(parseInt(e(r).css("borderTopWidth"),10)||0)-(parseInt(e(r).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=n}else t.containment.constructor==Array&&(this.containment=t.containment)},_convertPositionTo:function(t,n){n||(n=this.position);var r=t=="absolute"?1:-1,i=this.options,s=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(s[0].tagName);return{top:n.top+this.offset.relative.top*r+this.offset.parent.top*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():o?0:s.scrollTop())*r,left:n.left+this.offset.relative.left*r+this.offset.parent.left*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():o?0:s.scrollLeft())*r}},_generatePosition:function(t){var n=this.options,r=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,i=/(html|body)/i.test(r[0].tagName),s=t.pageX,o=t.pageY;if(this.originalPosition){var u;if(this.containment){if(this.relative_container){var a=this.relative_container.offset();u=[this.containment[0]+a.left,this.containment[1]+a.top,this.containment[2]+a.left,this.containment[3]+a.top]}else u=this.containment;t.pageX-this.offset.click.left<u[0]&&(s=u[0]+this.offset.click.left),t.pageY-this.offset.click.top<u[1]&&(o=u[1]+this.offset.click.top),t.pageX-this.offset.click.left>u[2]&&(s=u[2]+this.offset.click.left),t.pageY-this.offset.click.top>u[3]&&(o=u[3]+this.offset.click.top)}if(n.grid){var f=n.grid[1]?this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1]:this.originalPageY;o=u?f-this.offset.click.top<u[1]||f-this.offset.click.top>u[3]?f-this.offset.click.top<u[1]?f+n.grid[1]:f-n.grid[1]:f:f;var l=n.grid[0]?this.originalPageX+Math.round((s-this.originalPageX)/n.grid[0])*n.grid[0]:this.originalPageX;s=u?l-this.offset.click.left<u[0]||l-this.offset.click.left>u[2]?l-this.offset.click.left<u[0]?l+n.grid[0]:l-n.grid[0]:l:l}}return{top:o-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():i?0:r.scrollTop()),left:s-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():i?0:r.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(t,n,r){return r=r||this._uiHash(),e.ui.plugin.call(this,t,[n,r]),t=="drag"&&(this.positionAbs=this._convertPositionTo("absolute")),e.Widget.prototype._trigger.call(this,t,n,r)},plugins:{},_uiHash:function(e){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),e.ui.plugin.add("draggable","connectToSortable",{start:function(t,n){var r=e(this).data("draggable"),i=r.options,s=e.extend({},n,{item:r.element});r.sortables=[],e(i.connectToSortable).each(function(){var n=e.data(this,"sortable");n&&!n.options.disabled&&(r.sortables.push({instance:n,shouldRevert:n.options.revert}),n.refreshPositions(),n._trigger("activate",t,s))})},stop:function(t,n){var r=e(this).data("draggable"),i=e.extend({},n,{item:r.element});e.each(r.sortables,function(){this.instance.isOver?(this.instance.isOver=0,r.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=!0),this.instance._mouseStop(t),this.instance.options.helper=this.instance.options._helper,r.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",t,i))})},drag:function(t,n){var r=e(this).data("draggable"),i=this,s=function(t){var n=this.offset.click.top,r=this.offset.click.left,i=this.positionAbs.top,s=this.positionAbs.left,o=t.height,u=t.width,a=t.top,f=t.left;return e.ui.isOver(i+n,s+r,a,f,o,u)};e.each(r.sortables,function(s){var o=!1,u=this;this.instance.positionAbs=r.positionAbs,this.instance.helperProportions=r.helperProportions,this.instance.offset.click=r.offset.click,this.instance._intersectsWith(this.instance.containerCache)&&(o=!0,e.each(r.sortables,function(){return this.instance.positionAbs=r.positionAbs,this.instance.helperProportions=r.helperProportions,this.instance.offset.click=r.offset.click,this!=u&&this.instance._intersectsWith(this.instance.containerCache)&&e.ui.contains(u.instance.element[0],this.instance.element[0])&&(o=!1),o})),o?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=e(i).clone().removeAttr("id").appendTo(this.instance.element).data("sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return n.helper[0]},t.target=this.instance.currentItem[0],this.instance._mouseCapture(t,!0),this.instance._mouseStart(t,!0,!0),this.instance.offset.click.top=r.offset.click.top,this.instance.offset.click.left=r.offset.click.left,this.instance.offset.parent.left-=r.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=r.offset.parent.top-this.instance.offset.parent.top,r._trigger("toSortable",t),r.dropped=this.instance.element,r.currentItem=r.element,this.instance.fromOutside=r),this.instance.currentItem&&this.instance._mouseDrag(t)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",t,this.instance._uiHash(this.instance)),this.instance._mouseStop(t,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),r._trigger("fromSortable",t),r.dropped=!1)})}}),e.ui.plugin.add("draggable","cursor",{start:function(t,n){var r=e("body"),i=e(this).data("draggable").options;r.css("cursor")&&(i._cursor=r.css("cursor")),r.css("cursor",i.cursor)},stop:function(t,n){var r=e(this).data("draggable").options;r._cursor&&e("body").css("cursor",r._cursor)}}),e.ui.plugin.add("draggable","opacity",{start:function(t,n){var r=e(n.helper),i=e(this).data("draggable").options;r.css("opacity")&&(i._opacity=r.css("opacity")),r.css("opacity",i.opacity)},stop:function(t,n){var r=e(this).data("draggable").options;r._opacity&&e(n.helper).css("opacity",r._opacity)}}),e.ui.plugin.add("draggable","scroll",{start:function(t,n){var r=e(this).data("draggable");r.scrollParent[0]!=document&&r.scrollParent[0].tagName!="HTML"&&(r.overflowOffset=r.scrollParent.offset())},drag:function(t,n){var r=e(this).data("draggable"),i=r.options,s=!1;if(r.scrollParent[0]!=document&&r.scrollParent[0].tagName!="HTML"){if(!i.axis||i.axis!="x")r.overflowOffset.top+r.scrollParent[0].offsetHeight-t.pageY<i.scrollSensitivity?r.scrollParent[0].scrollTop=s=r.scrollParent[0].scrollTop+i.scrollSpeed:t.pageY-r.overflowOffset.top<i.scrollSensitivity&&(r.scrollParent[0].scrollTop=s=r.scrollParent[0].scrollTop-i.scrollSpeed);if(!i.axis||i.axis!="y")r.overflowOffset.left+r.scrollParent[0].offsetWidth-t.pageX<i.scrollSensitivity?r.scrollParent[0].scrollLeft=s=r.scrollParent[0].scrollLeft+i.scrollSpeed:t.pageX-r.overflowOffset.left<i.scrollSensitivity&&(r.scrollParent[0].scrollLeft=s=r.scrollParent[0].scrollLeft-i.scrollSpeed)}else{if(!i.axis||i.axis!="x")t.pageY-e(document).scrollTop()<i.scrollSensitivity?s=e(document).scrollTop(e(document).scrollTop()-i.scrollSpeed):e(window).height()-(t.pageY-e(document).scrollTop())<i.scrollSensitivity&&(s=e(document).scrollTop(e(document).scrollTop()+i.scrollSpeed));if(!i.axis||i.axis!="y")t.pageX-e(document).scrollLeft()<i.scrollSensitivity?s=e(document).scrollLeft(e(document).scrollLeft()-i.scrollSpeed):e(window).width()-(t.pageX-e(document).scrollLeft())<i.scrollSensitivity&&(s=e(document).scrollLeft(e(document).scrollLeft()+i.scrollSpeed))}s!==!1&&e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(r,t)}}),e.ui.plugin.add("draggable","snap",{start:function(t,n){var r=e(this).data("draggable"),i=r.options;r.snapElements=[],e(i.snap.constructor!=String?i.snap.items||":data(draggable)":i.snap).each(function(){var t=e(this),n=t.offset();this!=r.element[0]&&r.snapElements.push({item:this,width:t.outerWidth(),height:t.outerHeight(),top:n.top,left:n.left})})},drag:function(t,n){var r=e(this).data("draggable"),i=r.options,s=i.snapTolerance,o=n.offset.left,u=o+r.helperProportions.width,a=n.offset.top,f=a+r.helperProportions.height;for(var l=r.snapElements.length-1;l>=0;l--){var c=r.snapElements[l].left,h=c+r.snapElements[l].width,p=r.snapElements[l].top,d=p+r.snapElements[l].height;if(!(c-s<o&&o<h+s&&p-s<a&&a<d+s||c-s<o&&o<h+s&&p-s<f&&f<d+s||c-s<u&&u<h+s&&p-s<a&&a<d+s||c-s<u&&u<h+s&&p-s<f&&f<d+s)){r.snapElements[l].snapping&&r.options.snap.release&&r.options.snap.release.call(r.element,t,e.extend(r._uiHash(),{snapItem:r.snapElements[l].item})),r.snapElements[l].snapping=!1;continue}if(i.snapMode!="inner"){var v=Math.abs(p-f)<=s,m=Math.abs(d-a)<=s,g=Math.abs(c-u)<=s,y=Math.abs(h-o)<=s;v&&(n.position.top=r._convertPositionTo("relative",{top:p-r.helperProportions.height,left:0}).top-r.margins.top),m&&(n.position.top=r._convertPositionTo("relative",{top:d,left:0}).top-r.margins.top),g&&(n.position.left=r._convertPositionTo("relative",{top:0,left:c-r.helperProportions.width}).left-r.margins.left),y&&(n.position.left=r._convertPositionTo("relative",{top:0,left:h}).left-r.margins.left)}var b=v||m||g||y;if(i.snapMode!="outer"){var v=Math.abs(p-a)<=s,m=Math.abs(d-f)<=s,g=Math.abs(c-o)<=s,y=Math.abs(h-u)<=s;v&&(n.position.top=r._convertPositionTo("relative",{top:p,left:0}).top-r.margins.top),m&&(n.position.top=r._convertPositionTo("relative",{top:d-r.helperProportions.height,left:0}).top-r.margins.top),g&&(n.position.left=r._convertPositionTo("relative",{top:0,left:c}).left-r.margins.left),y&&(n.position.left=r._convertPositionTo("relative",{top:0,left:h-r.helperProportions.width}).left-r.margins.left)}!r.snapElements[l].snapping&&(v||m||g||y||b)&&r.options.snap.snap&&r.options.snap.snap.call(r.element,t,e.extend(r._uiHash(),{snapItem:r.snapElements[l].item})),r.snapElements[l].snapping=v||m||g||y||b}}}),e.ui.plugin.add("draggable","stack",{start:function(t,n){var r=e(this).data("draggable").options,i=e.makeArray(e(r.stack)).sort(function(t,n){return(parseInt(e(t).css("zIndex"),10)||0)-(parseInt(e(n).css("zIndex"),10)||0)});if(!i.length)return;var s=parseInt(i[0].style.zIndex)||0;e(i).each(function(e){this.style.zIndex=s+e}),this[0].style.zIndex=s+i.length}}),e.ui.plugin.add("draggable","zIndex",{start:function(t,n){var r=e(n.helper),i=e(this).data("draggable").options;r.css("zIndex")&&(i._zIndex=r.css("zIndex")),r.css("zIndex",i.zIndex)},stop:function(t,n){var r=e(this).data("draggable").options;r._zIndex&&e(n.helper).css("zIndex",r._zIndex)}})})(jQuery);(function(e,t){e.widget("ui.droppable",{version:"1.9.2",widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect"},_create:function(){var t=this.options,n=t.accept;this.isover=0,this.isout=1,this.accept=e.isFunction(n)?n:function(e){return e.is(n)},this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight},e.ui.ddmanager.droppables[t.scope]=e.ui.ddmanager.droppables[t.scope]||[],e.ui.ddmanager.droppables[t.scope].push(this),t.addClasses&&this.element.addClass("ui-droppable")},_destroy:function(){var t=e.ui.ddmanager.droppables[this.options.scope];for(var n=0;n<t.length;n++)t[n]==this&&t.splice(n,1);this.element.removeClass("ui-droppable ui-droppable-disabled")},_setOption:function(t,n){t=="accept"&&(this.accept=e.isFunction(n)?n:function(e){return e.is(n)}),e.Widget.prototype._setOption.apply(this,arguments)},_activate:function(t){var n=e.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),n&&this._trigger("activate",t,this.ui(n))},_deactivate:function(t){var n=e.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),n&&this._trigger("deactivate",t,this.ui(n))},_over:function(t){var n=e.ui.ddmanager.current;if(!n||(n.currentItem||n.element)[0]==this.element[0])return;this.accept.call(this.element[0],n.currentItem||n.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",t,this.ui(n)))},_out:function(t){var n=e.ui.ddmanager.current;if(!n||(n.currentItem||n.element)[0]==this.element[0])return;this.accept.call(this.element[0],n.currentItem||n.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",t,this.ui(n)))},_drop:function(t,n){var r=n||e.ui.ddmanager.current;if(!r||(r.currentItem||r.element)[0]==this.element[0])return!1;var i=!1;return this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var t=e.data(this,"droppable");if(t.options.greedy&&!t.options.disabled&&t.options.scope==r.options.scope&&t.accept.call(t.element[0],r.currentItem||r.element)&&e.ui.intersect(r,e.extend(t,{offset:t.element.offset()}),t.options.tolerance))return i=!0,!1}),i?!1:this.accept.call(this.element[0],r.currentItem||r.element)?(this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",t,this.ui(r)),this.element):!1},ui:function(e){return{draggable:e.currentItem||e.element,helper:e.helper,position:e.position,offset:e.positionAbs}}}),e.ui.intersect=function(t,n,r){if(!n.offset)return!1;var i=(t.positionAbs||t.position.absolute).left,s=i+t.helperProportions.width,o=(t.positionAbs||t.position.absolute).top,u=o+t.helperProportions.height,a=n.offset.left,f=a+n.proportions.width,l=n.offset.top,c=l+n.proportions.height;switch(r){case"fit":return a<=i&&s<=f&&l<=o&&u<=c;case"intersect":return a<i+t.helperProportions.width/2&&s-t.helperProportions.width/2<f&&l<o+t.helperProportions.height/2&&u-t.helperProportions.height/2<c;case"pointer":var h=(t.positionAbs||t.position.absolute).left+(t.clickOffset||t.offset.click).left,p=(t.positionAbs||t.position.absolute).top+(t.clickOffset||t.offset.click).top,d=e.ui.isOver(p,h,l,a,n.proportions.height,n.proportions.width);return d;case"touch":return(o>=l&&o<=c||u>=l&&u<=c||o<l&&u>c)&&(i>=a&&i<=f||s>=a&&s<=f||i<a&&s>f);default:return!1}},e.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(t,n){var r=e.ui.ddmanager.droppables[t.options.scope]||[],i=n?n.type:null,s=(t.currentItem||t.element).find(":data(droppable)").andSelf();e:for(var o=0;o<r.length;o++){if(r[o].options.disabled||t&&!r[o].accept.call(r[o].element[0],t.currentItem||t.element))continue;for(var u=0;u<s.length;u++)if(s[u]==r[o].element[0]){r[o].proportions.height=0;continue e}r[o].visible=r[o].element.css("display")!="none";if(!r[o].visible)continue;i=="mousedown"&&r[o]._activate.call(r[o],n),r[o].offset=r[o].element.offset(),r[o].proportions={width:r[o].element[0].offsetWidth,height:r[o].element[0].offsetHeight}}},drop:function(t,n){var r=!1;return e.each(e.ui.ddmanager.droppables[t.options.scope]||[],function(){if(!this.options)return;!this.options.disabled&&this.visible&&e.ui.intersect(t,this,this.options.tolerance)&&(r=this._drop.call(this,n)||r),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],t.currentItem||t.element)&&(this.isout=1,this.isover=0,this._deactivate.call(this,n))}),r},dragStart:function(t,n){t.element.parentsUntil("body").bind("scroll.droppable",function(){t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,n)})},drag:function(t,n){t.options.refreshPositions&&e.ui.ddmanager.prepareOffsets(t,n),e.each(e.ui.ddmanager.droppables[t.options.scope]||[],function(){if(this.options.disabled||this.greedyChild||!this.visible)return;var r=e.ui.intersect(t,this,this.options.tolerance),i=!r&&this.isover==1?"isout":r&&this.isover==0?"isover":null;if(!i)return;var s;if(this.options.greedy){var o=this.options.scope,u=this.element.parents(":data(droppable)").filter(function(){return e.data(this,"droppable").options.scope===o});u.length&&(s=e.data(u[0],"droppable"),s.greedyChild=i=="isover"?1:0)}s&&i=="isover"&&(s.isover=0,s.isout=1,s._out.call(s,n)),this[i]=1,this[i=="isout"?"isover":"isout"]=0,this[i=="isover"?"_over":"_out"].call(this,n),s&&i=="isout"&&(s.isout=0,s.isover=1,s._over.call(s,n))})},dragStop:function(t,n){t.element.parentsUntil("body").unbind("scroll.droppable"),t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,n)}}})(jQuery);jQuery.effects||function(e,t){var n=e.uiBackCompat!==!1,r="ui-effects-";e.effects={effect:{}},function(t,n){function p(e,t,n){var r=a[t.type]||{};return e==null?n||!t.def?null:t.def:(e=r.floor?~~e:parseFloat(e),isNaN(e)?t.def:r.mod?(e+r.mod)%r.mod:0>e?0:r.max<e?r.max:e)}function d(e){var n=o(),r=n._rgba=[];return e=e.toLowerCase(),h(s,function(t,i){var s,o=i.re.exec(e),a=o&&i.parse(o),f=i.space||"rgba";if(a)return s=n[f](a),n[u[f].cache]=s[u[f].cache],r=n._rgba=s._rgba,!1}),r.length?(r.join()==="0,0,0,0"&&t.extend(r,c.transparent),n):c[e]}function v(e,t,n){return n=(n+1)%1,n*6<1?e+(t-e)*n*6:n*2<1?t:n*3<2?e+(t-e)*(2/3-n)*6:e}var r="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "),i=/^([\-+])=\s*(\d+\.?\d*)/,s=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,parse:function(e){return[e[1],e[2],e[3],e[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,parse:function(e){return[e[1]*2.55,e[2]*2.55,e[3]*2.55,e[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(e){return[parseInt(e[1],16),parseInt(e[2],16),parseInt(e[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(e){return[parseInt(e[1]+e[1],16),parseInt(e[2]+e[2],16),parseInt(e[3]+e[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(e){return[e[1],e[2]/100,e[3]/100,e[4]]}}],o=t.Color=function(e,n,r,i){return new t.Color.fn.parse(e,n,r,i)},u={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},a={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},f=o.support={},l=t("<p>")[0],c,h=t.each;l.style.cssText="background-color:rgba(1,1,1,.5)",f.rgba=l.style.backgroundColor.indexOf("rgba")>-1,h(u,function(e,t){t.cache="_"+e,t.props.alpha={idx:3,type:"percent",def:1}}),o.fn=t.extend(o.prototype,{parse:function(r,i,s,a){if(r===n)return this._rgba=[null,null,null,null],this;if(r.jquery||r.nodeType)r=t(r).css(i),i=n;var f=this,l=t.type(r),v=this._rgba=[];i!==n&&(r=[r,i,s,a],l="array");if(l==="string")return this.parse(d(r)||c._default);if(l==="array")return h(u.rgba.props,function(e,t){v[t.idx]=p(r[t.idx],t)}),this;if(l==="object")return r instanceof o?h(u,function(e,t){r[t.cache]&&(f[t.cache]=r[t.cache].slice())}):h(u,function(t,n){var i=n.cache;h(n.props,function(e,t){if(!f[i]&&n.to){if(e==="alpha"||r[e]==null)return;f[i]=n.to(f._rgba)}f[i][t.idx]=p(r[e],t,!0)}),f[i]&&e.inArray(null,f[i].slice(0,3))<0&&(f[i][3]=1,n.from&&(f._rgba=n.from(f[i])))}),this},is:function(e){var t=o(e),n=!0,r=this;return h(u,function(e,i){var s,o=t[i.cache];return o&&(s=r[i.cache]||i.to&&i.to(r._rgba)||[],h(i.props,function(e,t){if(o[t.idx]!=null)return n=o[t.idx]===s[t.idx],n})),n}),n},_space:function(){var e=[],t=this;return h(u,function(n,r){t[r.cache]&&e.push(n)}),e.pop()},transition:function(e,t){var n=o(e),r=n._space(),i=u[r],s=this.alpha()===0?o("transparent"):this,f=s[i.cache]||i.to(s._rgba),l=f.slice();return n=n[i.cache],h(i.props,function(e,r){var i=r.idx,s=f[i],o=n[i],u=a[r.type]||{};if(o===null)return;s===null?l[i]=o:(u.mod&&(o-s>u.mod/2?s+=u.mod:s-o>u.mod/2&&(s-=u.mod)),l[i]=p((o-s)*t+s,r))}),this[r](l)},blend:function(e){if(this._rgba[3]===1)return this;var n=this._rgba.slice(),r=n.pop(),i=o(e)._rgba;return o(t.map(n,function(e,t){return(1-r)*i[t]+r*e}))},toRgbaString:function(){var e="rgba(",n=t.map(this._rgba,function(e,t){return e==null?t>2?1:0:e});return n[3]===1&&(n.pop(),e="rgb("),e+n.join()+")"},toHslaString:function(){var e="hsla(",n=t.map(this.hsla(),function(e,t){return e==null&&(e=t>2?1:0),t&&t<3&&(e=Math.round(e*100)+"%"),e});return n[3]===1&&(n.pop(),e="hsl("),e+n.join()+")"},toHexString:function(e){var n=this._rgba.slice(),r=n.pop();return e&&n.push(~~(r*255)),"#"+t.map(n,function(e){return e=(e||0).toString(16),e.length===1?"0"+e:e}).join("")},toString:function(){return this._rgba[3]===0?"transparent":this.toRgbaString()}}),o.fn.parse.prototype=o.fn,u.hsla.to=function(e){if(e[0]==null||e[1]==null||e[2]==null)return[null,null,null,e[3]];var t=e[0]/255,n=e[1]/255,r=e[2]/255,i=e[3],s=Math.max(t,n,r),o=Math.min(t,n,r),u=s-o,a=s+o,f=a*.5,l,c;return o===s?l=0:t===s?l=60*(n-r)/u+360:n===s?l=60*(r-t)/u+120:l=60*(t-n)/u+240,f===0||f===1?c=f:f<=.5?c=u/a:c=u/(2-a),[Math.round(l)%360,c,f,i==null?1:i]},u.hsla.from=function(e){if(e[0]==null||e[1]==null||e[2]==null)return[null,null,null,e[3]];var t=e[0]/360,n=e[1],r=e[2],i=e[3],s=r<=.5?r*(1+n):r+n-r*n,o=2*r-s;return[Math.round(v(o,s,t+1/3)*255),Math.round(v(o,s,t)*255),Math.round(v(o,s,t-1/3)*255),i]},h(u,function(e,r){var s=r.props,u=r.cache,a=r.to,f=r.from;o.fn[e]=function(e){a&&!this[u]&&(this[u]=a(this._rgba));if(e===n)return this[u].slice();var r,i=t.type(e),l=i==="array"||i==="object"?e:arguments,c=this[u].slice();return h(s,function(e,t){var n=l[i==="object"?e:t.idx];n==null&&(n=c[t.idx]),c[t.idx]=p(n,t)}),f?(r=o(f(c)),r[u]=c,r):o(c)},h(s,function(n,r){if(o.fn[n])return;o.fn[n]=function(s){var o=t.type(s),u=n==="alpha"?this._hsla?"hsla":"rgba":e,a=this[u](),f=a[r.idx],l;return o==="undefined"?f:(o==="function"&&(s=s.call(this,f),o=t.type(s)),s==null&&r.empty?this:(o==="string"&&(l=i.exec(s),l&&(s=f+parseFloat(l[2])*(l[1]==="+"?1:-1))),a[r.idx]=s,this[u](a)))}})}),h(r,function(e,n){t.cssHooks[n]={set:function(e,r){var i,s,u="";if(t.type(r)!=="string"||(i=d(r))){r=o(i||r);if(!f.rgba&&r._rgba[3]!==1){s=n==="backgroundColor"?e.parentNode:e;while((u===""||u==="transparent")&&s&&s.style)try{u=t.css(s,"backgroundColor"),s=s.parentNode}catch(a){}r=r.blend(u&&u!=="transparent"?u:"_default")}r=r.toRgbaString()}try{e.style[n]=r}catch(l){}}},t.fx.step[n]=function(e){e.colorInit||(e.start=o(e.elem,n),e.end=o(e.end),e.colorInit=!0),t.cssHooks[n].set(e.elem,e.start.transition(e.end,e.pos))}}),t.cssHooks.borderColor={expand:function(e){var t={};return h(["Top","Right","Bottom","Left"],function(n,r){t["border"+r+"Color"]=e}),t}},c=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery),function(){function i(){var t=this.ownerDocument.defaultView?this.ownerDocument.defaultView.getComputedStyle(this,null):this.currentStyle,n={},r,i;if(t&&t.length&&t[0]&&t[t[0]]){i=t.length;while(i--)r=t[i],typeof t[r]=="string"&&(n[e.camelCase(r)]=t[r])}else for(r in t)typeof t[r]=="string"&&(n[r]=t[r]);return n}function s(t,n){var i={},s,o;for(s in n)o=n[s],t[s]!==o&&!r[s]&&(e.fx.step[s]||!isNaN(parseFloat(o)))&&(i[s]=o);return i}var n=["add","remove","toggle"],r={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};e.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(t,n){e.fx.step[n]=function(e){if(e.end!=="none"&&!e.setAttr||e.pos===1&&!e.setAttr)jQuery.style(e.elem,n,e.end),e.setAttr=!0}}),e.effects.animateClass=function(t,r,o,u){var a=e.speed(r,o,u);return this.queue(function(){var r=e(this),o=r.attr("class")||"",u,f=a.children?r.find("*").andSelf():r;f=f.map(function(){var t=e(this);return{el:t,start:i.call(this)}}),u=function(){e.each(n,function(e,n){t[n]&&r[n+"Class"](t[n])})},u(),f=f.map(function(){return this.end=i.call(this.el[0]),this.diff=s(this.start,this.end),this}),r.attr("class",o),f=f.map(function(){var t=this,n=e.Deferred(),r=jQuery.extend({},a,{queue:!1,complete:function(){n.resolve(t)}});return this.el.animate(this.diff,r),n.promise()}),e.when.apply(e,f.get()).done(function(){u(),e.each(arguments,function(){var t=this.el;e.each(this.diff,function(e){t.css(e,"")})}),a.complete.call(r[0])})})},e.fn.extend({_addClass:e.fn.addClass,addClass:function(t,n,r,i){return n?e.effects.animateClass.call(this,{add:t},n,r,i):this._addClass(t)},_removeClass:e.fn.removeClass,removeClass:function(t,n,r,i){return n?e.effects.animateClass.call(this,{remove:t},n,r,i):this._removeClass(t)},_toggleClass:e.fn.toggleClass,toggleClass:function(n,r,i,s,o){return typeof r=="boolean"||r===t?i?e.effects.animateClass.call(this,r?{add:n}:{remove:n},i,s,o):this._toggleClass(n,r):e.effects.animateClass.call(this,{toggle:n},r,i,s)},switchClass:function(t,n,r,i,s){return e.effects.animateClass.call(this,{add:n,remove:t},r,i,s)}})}(),function(){function i(t,n,r,i){e.isPlainObject(t)&&(n=t,t=t.effect),t={effect:t},n==null&&(n={}),e.isFunction(n)&&(i=n,r=null,n={});if(typeof n=="number"||e.fx.speeds[n])i=r,r=n,n={};return e.isFunction(r)&&(i=r,r=null),n&&e.extend(t,n),r=r||n.duration,t.duration=e.fx.off?0:typeof r=="number"?r:r in e.fx.speeds?e.fx.speeds[r]:e.fx.speeds._default,t.complete=i||n.complete,t}function s(t){return!t||typeof t=="number"||e.fx.speeds[t]?!0:typeof t=="string"&&!e.effects.effect[t]?n&&e.effects[t]?!1:!0:!1}e.extend(e.effects,{version:"1.9.2",save:function(e,t){for(var n=0;n<t.length;n++)t[n]!==null&&e.data(r+t[n],e[0].style[t[n]])},restore:function(e,n){var i,s;for(s=0;s<n.length;s++)n[s]!==null&&(i=e.data(r+n[s]),i===t&&(i=""),e.css(n[s],i))},setMode:function(e,t){return t==="toggle"&&(t=e.is(":hidden")?"show":"hide"),t},getBaseline:function(e,t){var n,r;switch(e[0]){case"top":n=0;break;case"middle":n=.5;break;case"bottom":n=1;break;default:n=e[0]/t.height}switch(e[1]){case"left":r=0;break;case"center":r=.5;break;case"right":r=1;break;default:r=e[1]/t.width}return{x:r,y:n}},createWrapper:function(t){if(t.parent().is(".ui-effects-wrapper"))return t.parent();var n={width:t.outerWidth(!0),height:t.outerHeight(!0),"float":t.css("float")},r=e("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),i={width:t.width(),height:t.height()},s=document.activeElement;try{s.id}catch(o){s=document.body}return t.wrap(r),(t[0]===s||e.contains(t[0],s))&&e(s).focus(),r=t.parent(),t.css("position")==="static"?(r.css({position:"relative"}),t.css({position:"relative"})):(e.extend(n,{position:t.css("position"),zIndex:t.css("z-index")}),e.each(["top","left","bottom","right"],function(e,r){n[r]=t.css(r),isNaN(parseInt(n[r],10))&&(n[r]="auto")}),t.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),t.css(i),r.css(n).show()},removeWrapper:function(t){var n=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),(t[0]===n||e.contains(t[0],n))&&e(n).focus()),t},setTransition:function(t,n,r,i){return i=i||{},e.each(n,function(e,n){var s=t.cssUnit(n);s[0]>0&&(i[n]=s[0]*r+s[1])}),i}}),e.fn.extend({effect:function(){function a(n){function u(){e.isFunction(i)&&i.call(r[0]),e.isFunction(n)&&n()}var r=e(this),i=t.complete,s=t.mode;(r.is(":hidden")?s==="hide":s==="show")?u():o.call(r[0],t,u)}var t=i.apply(this,arguments),r=t.mode,s=t.queue,o=e.effects.effect[t.effect],u=!o&&n&&e.effects[t.effect];return e.fx.off||!o&&!u?r?this[r](t.duration,t.complete):this.each(function(){t.complete&&t.complete.call(this)}):o?s===!1?this.each(a):this.queue(s||"fx",a):u.call(this,{options:t,duration:t.duration,callback:t.complete,mode:t.mode})},_show:e.fn.show,show:function(e){if(s(e))return this._show.apply(this,arguments);var t=i.apply(this,arguments);return t.mode="show",this.effect.call(this,t)},_hide:e.fn.hide,hide:function(e){if(s(e))return this._hide.apply(this,arguments);var t=i.apply(this,arguments);return t.mode="hide",this.effect.call(this,t)},__toggle:e.fn.toggle,toggle:function(t){if(s(t)||typeof t=="boolean"||e.isFunction(t))return this.__toggle.apply(this,arguments);var n=i.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)},cssUnit:function(t){var n=this.css(t),r=[];return e.each(["em","px","%","pt"],function(e,t){n.indexOf(t)>0&&(r=[parseFloat(n),t])}),r}})}(),function(){var t={};e.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,n){t[n]=function(t){return Math.pow(t,e+2)}}),e.extend(t,{Sine:function(e){return 1-Math.cos(e*Math.PI/2)},Circ:function(e){return 1-Math.sqrt(1-e*e)},Elastic:function(e){return e===0||e===1?e:-Math.pow(2,8*(e-1))*Math.sin(((e-1)*80-7.5)*Math.PI/15)},Back:function(e){return e*e*(3*e-2)},Bounce:function(e){var t,n=4;while(e<((t=Math.pow(2,--n))-1)/11);return 1/Math.pow(4,3-n)-7.5625*Math.pow((t*3-2)/22-e,2)}}),e.each(t,function(t,n){e.easing["easeIn"+t]=n,e.easing["easeOut"+t]=function(e){return 1-n(1-e)},e.easing["easeInOut"+t]=function(e){return e<.5?n(e*2)/2:1-n(e*-2+2)/2}})}()}(jQuery);(function(e,t){var n=/up|down|vertical/,r=/up|left|vertical|horizontal/;e.effects.effect.blind=function(t,i){var s=e(this),o=["position","top","bottom","left","right","height","width"],u=e.effects.setMode(s,t.mode||"hide"),a=t.direction||"up",f=n.test(a),l=f?"height":"width",c=f?"top":"left",h=r.test(a),p={},d=u==="show",v,m,g;s.parent().is(".ui-effects-wrapper")?e.effects.save(s.parent(),o):e.effects.save(s,o),s.show(),v=e.effects.createWrapper(s).css({overflow:"hidden"}),m=v[l](),g=parseFloat(v.css(c))||0,p[l]=d?m:0,h||(s.css(f?"bottom":"right",0).css(f?"top":"left","auto").css({position:"absolute"}),p[c]=d?g:m+g),d&&(v.css(l,0),h||v.css(c,g+m)),v.animate(p,{duration:t.duration,easing:t.easing,queue:!1,complete:function(){u==="hide"&&s.hide(),e.effects.restore(s,o),e.effects.removeWrapper(s),i()}})}})(jQuery);(function(e,t){e.effects.effect.bounce=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"effect"),o=s==="hide",u=s==="show",a=t.direction||"up",f=t.distance,l=t.times||5,c=l*2+(u||o?1:0),h=t.duration/c,p=t.easing,d=a==="up"||a==="down"?"top":"left",v=a==="up"||a==="left",m,g,y,b=r.queue(),w=b.length;(u||o)&&i.push("opacity"),e.effects.save(r,i),r.show(),e.effects.createWrapper(r),f||(f=r[d==="top"?"outerHeight":"outerWidth"]()/3),u&&(y={opacity:1},y[d]=0,r.css("opacity",0).css(d,v?-f*2:f*2).animate(y,h,p)),o&&(f/=Math.pow(2,l-1)),y={},y[d]=0;for(m=0;m<l;m++)g={},g[d]=(v?"-=":"+=")+f,r.animate(g,h,p).animate(y,h,p),f=o?f*2:f/2;o&&(g={opacity:0},g[d]=(v?"-=":"+=")+f,r.animate(g,h,p)),r.queue(function(){o&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}),w>1&&b.splice.apply(b,[1,0].concat(b.splice(w,c+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.clip=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=t.direction||"vertical",a=u==="vertical",f=a?"height":"width",l=a?"top":"left",c={},h,p,d;e.effects.save(r,i),r.show(),h=e.effects.createWrapper(r).css({overflow:"hidden"}),p=r[0].tagName==="IMG"?h:r,d=p[f](),o&&(p.css(f,0),p.css(l,d/2)),c[f]=o?d:0,c[l]=o?0:d/2,p.animate(c,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){o||r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.drop=function(t,n){var r=e(this),i=["position","top","bottom","left","right","opacity","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=t.direction||"left",a=u==="up"||u==="down"?"top":"left",f=u==="up"||u==="left"?"pos":"neg",l={opacity:o?1:0},c;e.effects.save(r,i),r.show(),e.effects.createWrapper(r),c=t.distance||r[a==="top"?"outerHeight":"outerWidth"](!0)/2,o&&r.css("opacity",0).css(a,f==="pos"?-c:c),l[a]=(o?f==="pos"?"+=":"-=":f==="pos"?"-=":"+=")+c,r.animate(l,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.explode=function(t,n){function y(){c.push(this),c.length===r*i&&b()}function b(){s.css({visibility:"visible"}),e(c).remove(),u||s.hide(),n()}var r=t.pieces?Math.round(Math.sqrt(t.pieces)):3,i=r,s=e(this),o=e.effects.setMode(s,t.mode||"hide"),u=o==="show",a=s.show().css("visibility","hidden").offset(),f=Math.ceil(s.outerWidth()/i),l=Math.ceil(s.outerHeight()/r),c=[],h,p,d,v,m,g;for(h=0;h<r;h++){v=a.top+h*l,g=h-(r-1)/2;for(p=0;p<i;p++)d=a.left+p*f,m=p-(i-1)/2,s.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-p*f,top:-h*l}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:f,height:l,left:d+(u?m*f:0),top:v+(u?g*l:0),opacity:u?0:1}).animate({left:d+(u?0:m*f),top:v+(u?0:g*l),opacity:u?1:0},t.duration||500,t.easing,y)}}})(jQuery);(function(e,t){e.effects.effect.fade=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"toggle");r.animate({opacity:i},{queue:!1,duration:t.duration,easing:t.easing,complete:n})}})(jQuery);(function(e,t){e.effects.effect.fold=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=s==="hide",a=t.size||15,f=/([0-9]+)%/.exec(a),l=!!t.horizFirst,c=o!==l,h=c?["width","height"]:["height","width"],p=t.duration/2,d,v,m={},g={};e.effects.save(r,i),r.show(),d=e.effects.createWrapper(r).css({overflow:"hidden"}),v=c?[d.width(),d.height()]:[d.height(),d.width()],f&&(a=parseInt(f[1],10)/100*v[u?0:1]),o&&d.css(l?{height:0,width:a}:{height:a,width:0}),m[h[0]]=o?v[0]:a,g[h[1]]=o?v[1]:0,d.animate(m,p,t.easing).animate(g,p,t.easing,function(){u&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()})}})(jQuery);(function(e,t){e.effects.effect.highlight=function(t,n){var r=e(this),i=["backgroundImage","backgroundColor","opacity"],s=e.effects.setMode(r,t.mode||"show"),o={backgroundColor:r.css("backgroundColor")};s==="hide"&&(o.opacity=0),e.effects.save(r,i),r.show().css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(o,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),n()}})}})(jQuery);(function(e,t){e.effects.effect.pulsate=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"show"),s=i==="show",o=i==="hide",u=s||i==="hide",a=(t.times||5)*2+(u?1:0),f=t.duration/a,l=0,c=r.queue(),h=c.length,p;if(s||!r.is(":visible"))r.css("opacity",0).show(),l=1;for(p=1;p<a;p++)r.animate({opacity:l},f,t.easing),l=1-l;r.animate({opacity:l},f,t.easing),r.queue(function(){o&&r.hide(),n()}),h>1&&c.splice.apply(c,[1,0].concat(c.splice(h,a+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.puff=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"hide"),s=i==="hide",o=parseInt(t.percent,10)||150,u=o/100,a={height:r.height(),width:r.width(),outerHeight:r.outerHeight(),outerWidth:r.outerWidth()};e.extend(t,{effect:"scale",queue:!1,fade:!0,mode:i,complete:n,percent:s?o:100,from:s?a:{height:a.height*u,width:a.width*u,outerHeight:a.outerHeight*u,outerWidth:a.outerWidth*u}}),r.effect(t)},e.effects.effect.scale=function(t,n){var r=e(this),i=e.extend(!0,{},t),s=e.effects.setMode(r,t.mode||"effect"),o=parseInt(t.percent,10)||(parseInt(t.percent,10)===0?0:s==="hide"?0:100),u=t.direction||"both",a=t.origin,f={height:r.height(),width:r.width(),outerHeight:r.outerHeight(),outerWidth:r.outerWidth()},l={y:u!=="horizontal"?o/100:1,x:u!=="vertical"?o/100:1};i.effect="size",i.queue=!1,i.complete=n,s!=="effect"&&(i.origin=a||["middle","center"],i.restore=!0),i.from=t.from||(s==="show"?{height:0,width:0,outerHeight:0,outerWidth:0}:f),i.to={height:f.height*l.y,width:f.width*l.x,outerHeight:f.outerHeight*l.y,outerWidth:f.outerWidth*l.x},i.fade&&(s==="show"&&(i.from.opacity=0,i.to.opacity=1),s==="hide"&&(i.from.opacity=1,i.to.opacity=0)),r.effect(i)},e.effects.effect.size=function(t,n){var r,i,s,o=e(this),u=["position","top","bottom","left","right","width","height","overflow","opacity"],a=["position","top","bottom","left","right","overflow","opacity"],f=["width","height","overflow"],l=["fontSize"],c=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],h=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],p=e.effects.setMode(o,t.mode||"effect"),d=t.restore||p!=="effect",v=t.scale||"both",m=t.origin||["middle","center"],g=o.css("position"),y=d?u:a,b={height:0,width:0,outerHeight:0,outerWidth:0};p==="show"&&o.show(),r={height:o.height(),width:o.width(),outerHeight:o.outerHeight(),outerWidth:o.outerWidth()},t.mode==="toggle"&&p==="show"?(o.from=t.to||b,o.to=t.from||r):(o.from=t.from||(p==="show"?b:r),o.to=t.to||(p==="hide"?b:r)),s={from:{y:o.from.height/r.height,x:o.from.width/r.width},to:{y:o.to.height/r.height,x:o.to.width/r.width}};if(v==="box"||v==="both")s.from.y!==s.to.y&&(y=y.concat(c),o.from=e.effects.setTransition(o,c,s.from.y,o.from),o.to=e.effects.setTransition(o,c,s.to.y,o.to)),s.from.x!==s.to.x&&(y=y.concat(h),o.from=e.effects.setTransition(o,h,s.from.x,o.from),o.to=e.effects.setTransition(o,h,s.to.x,o.to));(v==="content"||v==="both")&&s.from.y!==s.to.y&&(y=y.concat(l).concat(f),o.from=e.effects.setTransition(o,l,s.from.y,o.from),o.to=e.effects.setTransition(o,l,s.to.y,o.to)),e.effects.save(o,y),o.show(),e.effects.createWrapper(o),o.css("overflow","hidden").css(o.from),m&&(i=e.effects.getBaseline(m,r),o.from.top=(r.outerHeight-o.outerHeight())*i.y,o.from.left=(r.outerWidth-o.outerWidth())*i.x,o.to.top=(r.outerHeight-o.to.outerHeight)*i.y,o.to.left=(r.outerWidth-o.to.outerWidth)*i.x),o.css(o.from);if(v==="content"||v==="both")c=c.concat(["marginTop","marginBottom"]).concat(l),h=h.concat(["marginLeft","marginRight"]),f=u.concat(c).concat(h),o.find("*[width]").each(function(){var n=e(this),r={height:n.height(),width:n.width(),outerHeight:n.outerHeight(),outerWidth:n.outerWidth()};d&&e.effects.save(n,f),n.from={height:r.height*s.from.y,width:r.width*s.from.x,outerHeight:r.outerHeight*s.from.y,outerWidth:r.outerWidth*s.from.x},n.to={height:r.height*s.to.y,width:r.width*s.to.x,outerHeight:r.height*s.to.y,outerWidth:r.width*s.to.x},s.from.y!==s.to.y&&(n.from=e.effects.setTransition(n,c,s.from.y,n.from),n.to=e.effects.setTransition(n,c,s.to.y,n.to)),s.from.x!==s.to.x&&(n.from=e.effects.setTransition(n,h,s.from.x,n.from),n.to=e.effects.setTransition(n,h,s.to.x,n.to)),n.css(n.from),n.animate(n.to,t.duration,t.easing,function(){d&&e.effects.restore(n,f)})});o.animate(o.to,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){o.to.opacity===0&&o.css("opacity",o.from.opacity),p==="hide"&&o.hide(),e.effects.restore(o,y),d||(g==="static"?o.css({position:"relative",top:o.to.top,left:o.to.left}):e.each(["top","left"],function(e,t){o.css(t,function(t,n){var r=parseInt(n,10),i=e?o.to.left:o.to.top;return n==="auto"?i+"px":r+i+"px"})})),e.effects.removeWrapper(o),n()}})}})(jQuery);(function(e,t){e.effects.effect.shake=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"effect"),o=t.direction||"left",u=t.distance||20,a=t.times||3,f=a*2+1,l=Math.round(t.duration/f),c=o==="up"||o==="down"?"top":"left",h=o==="up"||o==="left",p={},d={},v={},m,g=r.queue(),y=g.length;e.effects.save(r,i),r.show(),e.effects.createWrapper(r),p[c]=(h?"-=":"+=")+u,d[c]=(h?"+=":"-=")+u*2,v[c]=(h?"-=":"+=")+u*2,r.animate(p,l,t.easing);for(m=1;m<a;m++)r.animate(d,l,t.easing).animate(v,l,t.easing);r.animate(d,l,t.easing).animate(p,l/2,t.easing).queue(function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}),y>1&&g.splice.apply(g,[1,0].concat(g.splice(y,f+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.slide=function(t,n){var r=e(this),i=["position","top","bottom","left","right","width","height"],s=e.effects.setMode(r,t.mode||"show"),o=s==="show",u=t.direction||"left",a=u==="up"||u==="down"?"top":"left",f=u==="up"||u==="left",l,c={};e.effects.save(r,i),r.show(),l=t.distance||r[a==="top"?"outerHeight":"outerWidth"](!0),e.effects.createWrapper(r).css({overflow:"hidden"}),o&&r.css(a,f?isNaN(l)?"-"+l:-l:l),c[a]=(o?f?"+=":"-=":f?"-=":"+=")+l,r.animate(c,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.transfer=function(t,n){var r=e(this),i=e(t.to),s=i.css("position")==="fixed",o=e("body"),u=s?o.scrollTop():0,a=s?o.scrollLeft():0,f=i.offset(),l={top:f.top-u,left:f.left-a,height:i.innerHeight(),width:i.innerWidth()},c=r.offset(),h=e('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(t.className).css({top:c.top-u,left:c.left-a,height:r.innerHeight(),width:r.innerWidth(),position:s?"fixed":"absolute"}).animate(l,t.duration,t.easing,function(){h.remove(),n()})}})(jQuery);(function(e,t){var n=!1;e.widget("ui.menu",{version:"1.9.2",defaultElement:"<ul>",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content ui-corner-all").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}).bind("click"+this.eventNamespace,e.proxy(function(e){this.options.disabled&&e.preventDefault()},this)),this.options.disabled&&this.element.addClass("ui-state-disabled").attr("aria-disabled","true"),this._on({"mousedown .ui-menu-item > a":function(e){e.preventDefault()},"click .ui-state-disabled > a":function(e){e.preventDefault()},"click .ui-menu-item:has(a)":function(t){var r=e(t.target).closest(".ui-menu-item");!n&&r.not(".ui-state-disabled").length&&(n=!0,this.select(t),r.has(".ui-menu").length?this.expand(t):this.element.is(":focus")||(this.element.trigger("focus",[!0]),this.active&&this.active.parents(".ui-menu").length===1&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(t){var n=e(t.currentTarget);n.siblings().children(".ui-state-active").removeClass("ui-state-active"),this.focus(t,n)},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(e,t){var n=this.active||this.element.children(".ui-menu-item").eq(0);t||this.focus(e,n)},blur:function(t){this._delay(function(){e.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){e(t.target).closest(".ui-menu").length||this.collapseAll(t),n=!1}})},_destroy:function(){this.element.removeAttr("aria-activedescendant").find(".ui-menu").andSelf().removeClass("ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show(),this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").children("a").removeUniqueId().removeClass("ui-corner-all ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var t=e(this);t.data("ui-menu-submenu-carat")&&t.remove()}),this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(t){function a(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}var n,r,i,s,o,u=!0;switch(t.keyCode){case e.ui.keyCode.PAGE_UP:this.previousPage(t);break;case e.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case e.ui.keyCode.HOME:this._move("first","first",t);break;case e.ui.keyCode.END:this._move("last","last",t);break;case e.ui.keyCode.UP:this.previous(t);break;case e.ui.keyCode.DOWN:this.next(t);break;case e.ui.keyCode.LEFT:this.collapse(t);break;case e.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case e.ui.keyCode.ENTER:case e.ui.keyCode.SPACE:this._activate(t);break;case e.ui.keyCode.ESCAPE:this.collapse(t);break;default:u=!1,r=this.previousFilter||"",i=String.fromCharCode(t.keyCode),s=!1,clearTimeout(this.filterTimer),i===r?s=!0:i=r+i,o=new RegExp("^"+a(i),"i"),n=this.activeMenu.children(".ui-menu-item").filter(function(){return o.test(e(this).children("a").text())}),n=s&&n.index(this.active.next())!==-1?this.active.nextAll(".ui-menu-item"):n,n.length||(i=String.fromCharCode(t.keyCode),o=new RegExp("^"+a(i),"i"),n=this.activeMenu.children(".ui-menu-item").filter(function(){return o.test(e(this).children("a").text())})),n.length?(this.focus(t,n),n.length>1?(this.previousFilter=i,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter):delete this.previousFilter}u&&t.preventDefault()},_activate:function(e){this.active.is(".ui-state-disabled")||(this.active.children("a[aria-haspopup='true']").length?this.expand(e):this.select(e))},refresh:function(){var t,n=this.options.icons.submenu,r=this.element.find(this.options.menus);r.filter(":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-corner-all").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=e(this),r=t.prev("a"),i=e("<span>").addClass("ui-menu-icon ui-icon "+n).data("ui-menu-submenu-carat",!0);r.attr("aria-haspopup","true").prepend(i),t.attr("aria-labelledby",r.attr("id"))}),t=r.add(this.element),t.children(":not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","presentation").children("a").uniqueId().addClass("ui-corner-all").attr({tabIndex:-1,role:this._itemRole()}),t.children(":not(.ui-menu-item)").each(function(){var t=e(this);/[^\-—–\s]/.test(t.text())||t.addClass("ui-widget-content ui-menu-divider")}),t.children(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!e.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},focus:function(e,t){var n,r;this.blur(e,e&&e.type==="focus"),this._scrollIntoView(t),this.active=t.first(),r=this.active.children("a").addClass("ui-state-focus"),this.options.role&&this.element.attr("aria-activedescendant",r.attr("id")),this.active.parent().closest(".ui-menu-item").children("a:first").addClass("ui-state-active"),e&&e.type==="keydown"?this._close():this.timer=this._delay(function(){this._close()},this.delay),n=t.children(".ui-menu"),n.length&&/^mouse/.test(e.type)&&this._startOpening(n),this.activeMenu=t.parent(),this._trigger("focus",e,{item:t})},_scrollIntoView:function(t){var n,r,i,s,o,u;this._hasScroll()&&(n=parseFloat(e.css(this.activeMenu[0],"borderTopWidth"))||0,r=parseFloat(e.css(this.activeMenu[0],"paddingTop"))||0,i=t.offset().top-this.activeMenu.offset().top-n-r,s=this.activeMenu.scrollTop(),o=this.activeMenu.height(),u=t.height(),i<0?this.activeMenu.scrollTop(s+i):i+u>o&&this.activeMenu.scrollTop(s+i-o+u))},blur:function(e,t){t||clearTimeout(this.timer);if(!this.active)return;this.active.children("a").removeClass("ui-state-focus"),this.active=null,this._trigger("blur",e,{item:this.active})},_startOpening:function(e){clearTimeout(this.timer);if(e.attr("aria-hidden")!=="true")return;this.timer=this._delay(function(){this._close(),this._open(e)},this.delay)},_open:function(t){var n=e.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(t.parents(".ui-menu")).hide().attr("aria-hidden","true"),t.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(n)},collapseAll:function(t,n){clearTimeout(this.timer),this.timer=this._delay(function(){var r=n?this.element:e(t&&t.target).closest(this.element.find(".ui-menu"));r.length||(r=this.element),this._close(r),this.blur(t),this.activeMenu=r},this.delay)},_close:function(e){e||(e=this.active?this.active.parent():this.element),e.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find("a.ui-state-active").removeClass("ui-state-active")},collapse:function(e){var t=this.active&&this.active.parent().closest(".ui-menu-item",this.element);t&&t.length&&(this._close(),this.focus(e,t))},expand:function(e){var t=this.active&&this.active.children(".ui-menu ").children(".ui-menu-item").first();t&&t.length&&(this._open(t.parent()),this._delay(function(){this.focus(e,t)}))},next:function(e){this._move("next","first",e)},previous:function(e){this._move("prev","last",e)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(e,t,n){var r;this.active&&(e==="first"||e==="last"?r=this.active[e==="first"?"prevAll":"nextAll"](".ui-menu-item").eq(-1):r=this.active[e+"All"](".ui-menu-item").eq(0));if(!r||!r.length||!this.active)r=this.activeMenu.children(".ui-menu-item")[t]();this.focus(n,r)},nextPage:function(t){var n,r,i;if(!this.active){this.next(t);return}if(this.isLastItem())return;this._hasScroll()?(r=this.active.offset().top,i=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return n=e(this),n.offset().top-r-i<0}),this.focus(t,n)):this.focus(t,this.activeMenu.children(".ui-menu-item")[this.active?"last":"first"]())},previousPage:function(t){var n,r,i;if(!this.active){this.next(t);return}if(this.isFirstItem())return;this._hasScroll()?(r=this.active.offset().top,i=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return n=e(this),n.offset().top-r+i>0}),this.focus(t,n)):this.focus(t,this.activeMenu.children(".ui-menu-item").first())},_hasScroll:function(){return this.element.outerHeight()<this.element.prop("scrollHeight")},select:function(t){this.active=this.active||e(t.target).closest(".ui-menu-item");var n={item:this.active};this.active.has(".ui-menu").length||this.collapseAll(t,!0),this._trigger("select",t,n)}})})(jQuery);(function(e,t){e.widget("ui.progressbar",{version:"1.9.2",options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()}),this.valueDiv=e("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element),this.oldValue=this._value(),this._refreshValue()},_destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove()},value:function(e){return e===t?this._value():(this._setOption("value",e),this)},_setOption:function(e,t){e==="value"&&(this.options.value=t,this._refreshValue(),this._value()===this.options.max&&this._trigger("complete")),this._super(e,t)},_value:function(){var e=this.options.value;return typeof e!="number"&&(e=0),Math.min(this.options.max,Math.max(this.min,e))},_percentage:function(){return 100*this._value()/this.options.max},_refreshValue:function(){var e=this.value(),t=this._percentage();this.oldValue!==e&&(this.oldValue=e,this._trigger("change")),this.valueDiv.toggle(e>this.min).toggleClass("ui-corner-right",e===this.options.max).width(t.toFixed(0)+"%"),this.element.attr("aria-valuenow",e)}})})(jQuery);(function(e,t){e.widget("ui.resizable",e.ui.mouse,{version:"1.9.2",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1e3},_create:function(){var t=this,n=this.options;this.element.addClass("ui-resizable"),e.extend(this,{_aspectRatio:!!n.aspectRatio,aspectRatio:n.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:n.helper||n.ghost||n.animate?n.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(e('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("resizable",this.element.data("resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=n.handles||(e(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se");if(this.handles.constructor==String){this.handles=="all"&&(this.handles="n,e,s,w,se,sw,ne,nw");var r=this.handles.split(",");this.handles={};for(var i=0;i<r.length;i++){var s=e.trim(r[i]),o="ui-resizable-"+s,u=e('<div class="ui-resizable-handle '+o+'"></div>');u.css({zIndex:n.zIndex}),"se"==s&&u.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[s]=".ui-resizable-"+s,this.element.append(u)}}this._renderAxis=function(t){t=t||this.element;for(var n in this.handles){this.handles[n].constructor==String&&(this.handles[n]=e(this.handles[n],this.element).show());if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var r=e(this.handles[n],this.element),i=0;i=/sw|ne|nw|se|n|s/.test(n)?r.outerHeight():r.outerWidth();var s=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");t.css(s,i),this._proportionallyResize()}if(!e(this.handles[n]).length)continue}},this._renderAxis(this.element),this._handles=e(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){if(!t.resizing){if(this.className)var e=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);t.axis=e&&e[1]?e[1]:"se"}}),n.autoHide&&(this._handles.hide(),e(this.element).addClass("ui-resizable-autohide").mouseenter(function(){if(n.disabled)return;e(this).removeClass("ui-resizable-autohide"),t._handles.show()}).mouseleave(function(){if(n.disabled)return;t.resizing||(e(this).addClass("ui-resizable-autohide"),t._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var t=function(t){e(t).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){t(this.element);var n=this.element;this.originalElement.css({position:n.css("position"),width:n.outerWidth(),height:n.outerHeight(),top:n.css("top"),left:n.css("left")}).insertAfter(n),n.remove()}return this.originalElement.css("resize",this.originalResizeStyle),t(this.originalElement),this},_mouseCapture:function(t){var n=!1;for(var r in this.handles)e(this.handles[r])[0]==t.target&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(t){var r=this.options,i=this.element.position(),s=this.element;this.resizing=!0,this.documentScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()},(s.is(".ui-draggable")||/absolute/.test(s.css("position")))&&s.css({position:"absolute",top:i.top,left:i.left}),this._renderProxy();var o=n(this.helper.css("left")),u=n(this.helper.css("top"));r.containment&&(o+=e(r.containment).scrollLeft()||0,u+=e(r.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:o,top:u},this.size=this._helper?{width:s.outerWidth(),height:s.outerHeight()}:{width:s.width(),height:s.height()},this.originalSize=this._helper?{width:s.outerWidth(),height:s.outerHeight()}:{width:s.width(),height:s.height()},this.originalPosition={left:o,top:u},this.sizeDiff={width:s.outerWidth()-s.width(),height:s.outerHeight()-s.height()},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio=typeof r.aspectRatio=="number"?r.aspectRatio:this.originalSize.width/this.originalSize.height||1;var a=e(".ui-resizable-"+this.axis).css("cursor");return e("body").css("cursor",a=="auto"?this.axis+"-resize":a),s.addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(e){var t=this.helper,n=this.options,r={},i=this,s=this.originalMousePosition,o=this.axis,u=e.pageX-s.left||0,a=e.pageY-s.top||0,f=this._change[o];if(!f)return!1;var l=f.apply(this,[e,u,a]);this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey)l=this._updateRatio(l,e);return l=this._respectSize(l,e),this._propagate("resize",e),t.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"}),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),this._updateCache(l),this._trigger("resize",e,this.ui()),!1},_mouseStop:function(t){this.resizing=!1;var n=this.options,r=this;if(this._helper){var i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),o=s&&e.ui.hasScroll(i[0],"left")?0:r.sizeDiff.height,u=s?0:r.sizeDiff.width,a={width:r.helper.width()-u,height:r.helper.height()-o},f=parseInt(r.element.css("left"),10)+(r.position.left-r.originalPosition.left)||null,l=parseInt(r.element.css("top"),10)+(r.position.top-r.originalPosition.top)||null;n.animate||this.element.css(e.extend(a,{top:l,left:f})),r.helper.height(r.size.height),r.helper.width(r.size.width),this._helper&&!n.animate&&this._proportionallyResize()}return e("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(e){var t=this.options,n,i,s,o,u;u={minWidth:r(t.minWidth)?t.minWidth:0,maxWidth:r(t.maxWidth)?t.maxWidth:Infinity,minHeight:r(t.minHeight)?t.minHeight:0,maxHeight:r(t.maxHeight)?t.maxHeight:Infinity};if(this._aspectRatio||e)n=u.minHeight*this.aspectRatio,s=u.minWidth/this.aspectRatio,i=u.maxHeight*this.aspectRatio,o=u.maxWidth/this.aspectRatio,n>u.minWidth&&(u.minWidth=n),s>u.minHeight&&(u.minHeight=s),i<u.maxWidth&&(u.maxWidth=i),o<u.maxHeight&&(u.maxHeight=o);this._vBoundaries=u},_updateCache:function(e){var t=this.options;this.offset=this.helper.offset(),r(e.left)&&(this.position.left=e.left),r(e.top)&&(this.position.top=e.top),r(e.height)&&(this.size.height=e.height),r(e.width)&&(this.size.width=e.width)},_updateRatio:function(e,t){var n=this.options,i=this.position,s=this.size,o=this.axis;return r(e.height)?e.width=e.height*this.aspectRatio:r(e.width)&&(e.height=e.width/this.aspectRatio),o=="sw"&&(e.left=i.left+(s.width-e.width),e.top=null),o=="nw"&&(e.top=i.top+(s.height-e.height),e.left=i.left+(s.width-e.width)),e},_respectSize:function(e,t){var n=this.helper,i=this._vBoundaries,s=this._aspectRatio||t.shiftKey,o=this.axis,u=r(e.width)&&i.maxWidth&&i.maxWidth<e.width,a=r(e.height)&&i.maxHeight&&i.maxHeight<e.height,f=r(e.width)&&i.minWidth&&i.minWidth>e.width,l=r(e.height)&&i.minHeight&&i.minHeight>e.height;f&&(e.width=i.minWidth),l&&(e.height=i.minHeight),u&&(e.width=i.maxWidth),a&&(e.height=i.maxHeight);var c=this.originalPosition.left+this.originalSize.width,h=this.position.top+this.size.height,p=/sw|nw|w/.test(o),d=/nw|ne|n/.test(o);f&&p&&(e.left=c-i.minWidth),u&&p&&(e.left=c-i.maxWidth),l&&d&&(e.top=h-i.minHeight),a&&d&&(e.top=h-i.maxHeight);var v=!e.width&&!e.height;return v&&!e.left&&e.top?e.top=null:v&&!e.top&&e.left&&(e.left=null),e},_proportionallyResize:function(){var t=this.options;if(!this._proportionallyResizeElements.length)return;var n=this.helper||this.element;for(var r=0;r<this._proportionallyResizeElements.length;r++){var i=this._proportionallyResizeElements[r];if(!this.borderDif){var s=[i.css("borderTopWidth"),i.css("borderRightWidth"),i.css("borderBottomWidth"),i.css("borderLeftWidth")],o=[i.css("paddingTop"),i.css("paddingRight"),i.css("paddingBottom"),i.css("paddingLeft")];this.borderDif=e.map(s,function(e,t){var n=parseInt(e,10)||0,r=parseInt(o[t],10)||0;return n+r})}i.css({height:n.height()-this.borderDif[0]-this.borderDif[2]||0,width:n.width()-this.borderDif[1]-this.borderDif[3]||0})}},_renderProxy:function(){var t=this.element,n=this.options;this.elementOffset=t.offset();if(this._helper){this.helper=this.helper||e('<div style="overflow:hidden;"></div>');var r=e.ui.ie6?1:0,i=e.ui.ie6?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+i,height:this.element.outerHeight()+i,position:"absolute",left:this.elementOffset.left-r+"px",top:this.elementOffset.top-r+"px",zIndex:++n.zIndex}),this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(e,t,n){return{width:this.originalSize.width+t}},w:function(e,t,n){var r=this.options,i=this.originalSize,s=this.originalPosition;return{left:s.left+t,width:i.width-t}},n:function(e,t,n){var r=this.options,i=this.originalSize,s=this.originalPosition;return{top:s.top+n,height:i.height-n}},s:function(e,t,n){return{height:this.originalSize.height+n}},se:function(t,n,r){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,n,r]))},sw:function(t,n,r){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,n,r]))},ne:function(t,n,r){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,n,r]))},nw:function(t,n,r){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,n,r]))}},_propagate:function(t,n){e.ui.plugin.call(this,t,[n,this.ui()]),t!="resize"&&this._trigger(t,n,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),e.ui.plugin.add("resizable","alsoResize",{start:function(t,n){var r=e(this).data("resizable"),i=r.options,s=function(t){e(t).each(function(){var t=e(this);t.data("resizable-alsoresize",{width:parseInt(t.width(),10),height:parseInt(t.height(),10),left:parseInt(t.css("left"),10),top:parseInt(t.css("top"),10)})})};typeof i.alsoResize=="object"&&!i.alsoResize.parentNode?i.alsoResize.length?(i.alsoResize=i.alsoResize[0],s(i.alsoResize)):e.each(i.alsoResize,function(e){s(e)}):s(i.alsoResize)},resize:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.originalSize,o=r.originalPosition,u={height:r.size.height-s.height||0,width:r.size.width-s.width||0,top:r.position.top-o.top||0,left:r.position.left-o.left||0},a=function(t,r){e(t).each(function(){var t=e(this),i=e(this).data("resizable-alsoresize"),s={},o=r&&r.length?r:t.parents(n.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(o,function(e,t){var n=(i[t]||0)+(u[t]||0);n&&n>=0&&(s[t]=n||null)}),t.css(s)})};typeof i.alsoResize=="object"&&!i.alsoResize.nodeType?e.each(i.alsoResize,function(e,t){a(e,t)}):a(i.alsoResize)},stop:function(t,n){e(this).removeData("resizable-alsoresize")}}),e.ui.plugin.add("resizable","animate",{stop:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r._proportionallyResizeElements,o=s.length&&/textarea/i.test(s[0].nodeName),u=o&&e.ui.hasScroll(s[0],"left")?0:r.sizeDiff.height,a=o?0:r.sizeDiff.width,f={width:r.size.width-a,height:r.size.height-u},l=parseInt(r.element.css("left"),10)+(r.position.left-r.originalPosition.left)||null,c=parseInt(r.element.css("top"),10)+(r.position.top-r.originalPosition.top)||null;r.element.animate(e.extend(f,c&&l?{top:c,left:l}:{}),{duration:i.animateDuration,easing:i.animateEasing,step:function(){var n={width:parseInt(r.element.css("width"),10),height:parseInt(r.element.css("height"),10),top:parseInt(r.element.css("top"),10),left:parseInt(r.element.css("left"),10)};s&&s.length&&e(s[0]).css({width:n.width,height:n.height}),r._updateCache(n),r._propagate("resize",t)}})}}),e.ui.plugin.add("resizable","containment",{start:function(t,r){var i=e(this).data("resizable"),s=i.options,o=i.element,u=s.containment,a=u instanceof e?u.get(0):/parent/.test(u)?o.parent().get(0):u;if(!a)return;i.containerElement=e(a);if(/document/.test(u)||u==document)i.containerOffset={left:0,top:0},i.containerPosition={left:0,top:0},i.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight};else{var f=e(a),l=[];e(["Top","Right","Left","Bottom"]).each(function(e,t){l[e]=n(f.css("padding"+t))}),i.containerOffset=f.offset(),i.containerPosition=f.position(),i.containerSize={height:f.innerHeight()-l[3],width:f.innerWidth()-l[1]};var c=i.containerOffset,h=i.containerSize.height,p=i.containerSize.width,d=e.ui.hasScroll(a,"left")?a.scrollWidth:p,v=e.ui.hasScroll(a)?a.scrollHeight:h;i.parentData={element:a,left:c.left,top:c.top,width:d,height:v}}},resize:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.containerSize,o=r.containerOffset,u=r.size,a=r.position,f=r._aspectRatio||t.shiftKey,l={top:0,left:0},c=r.containerElement;c[0]!=document&&/static/.test(c.css("position"))&&(l=o),a.left<(r._helper?o.left:0)&&(r.size.width=r.size.width+(r._helper?r.position.left-o.left:r.position.left-l.left),f&&(r.size.height=r.size.width/r.aspectRatio),r.position.left=i.helper?o.left:0),a.top<(r._helper?o.top:0)&&(r.size.height=r.size.height+(r._helper?r.position.top-o.top:r.position.top),f&&(r.size.width=r.size.height*r.aspectRatio),r.position.top=r._helper?o.top:0),r.offset.left=r.parentData.left+r.position.left,r.offset.top=r.parentData.top+r.position.top;var h=Math.abs((r._helper?r.offset.left-l.left:r.offset.left-l.left)+r.sizeDiff.width),p=Math.abs((r._helper?r.offset.top-l.top:r.offset.top-o.top)+r.sizeDiff.height),d=r.containerElement.get(0)==r.element.parent().get(0),v=/relative|absolute/.test(r.containerElement.css("position"));d&&v&&(h-=r.parentData.left),h+r.size.width>=r.parentData.width&&(r.size.width=r.parentData.width-h,f&&(r.size.height=r.size.width/r.aspectRatio)),p+r.size.height>=r.parentData.height&&(r.size.height=r.parentData.height-p,f&&(r.size.width=r.size.height*r.aspectRatio))},stop:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.position,o=r.containerOffset,u=r.containerPosition,a=r.containerElement,f=e(r.helper),l=f.offset(),c=f.outerWidth()-r.sizeDiff.width,h=f.outerHeight()-r.sizeDiff.height;r._helper&&!i.animate&&/relative/.test(a.css("position"))&&e(this).css({left:l.left-u.left-o.left,width:c,height:h}),r._helper&&!i.animate&&/static/.test(a.css("position"))&&e(this).css({left:l.left-u.left-o.left,width:c,height:h})}}),e.ui.plugin.add("resizable","ghost",{start:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.size;r.ghost=r.originalElement.clone(),r.ghost.css({opacity:.25,display:"block",position:"relative",height:s.height,width:s.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:""),r.ghost.appendTo(r.helper)},resize:function(t,n){var r=e(this).data("resizable"),i=r.options;r.ghost&&r.ghost.css({position:"relative",height:r.size.height,width:r.size.width})},stop:function(t,n){var r=e(this).data("resizable"),i=r.options;r.ghost&&r.helper&&r.helper.get(0).removeChild(r.ghost.get(0))}}),e.ui.plugin.add("resizable","grid",{resize:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.size,o=r.originalSize,u=r.originalPosition,a=r.axis,f=i._aspectRatio||t.shiftKey;i.grid=typeof i.grid=="number"?[i.grid,i.grid]:i.grid;var l=Math.round((s.width-o.width)/(i.grid[0]||1))*(i.grid[0]||1),c=Math.round((s.height-o.height)/(i.grid[1]||1))*(i.grid[1]||1);/^(se|s|e)$/.test(a)?(r.size.width=o.width+l,r.size.height=o.height+c):/^(ne)$/.test(a)?(r.size.width=o.width+l,r.size.height=o.height+c,r.position.top=u.top-c):/^(sw)$/.test(a)?(r.size.width=o.width+l,r.size.height=o.height+c,r.position.left=u.left-l):(r.size.width=o.width+l,r.size.height=o.height+c,r.position.top=u.top-c,r.position.left=u.left-l)}});var n=function(e){return parseInt(e,10)||0},r=function(e){return!isNaN(parseInt(e,10))}})(jQuery);(function(e,t){e.widget("ui.selectable",e.ui.mouse,{version:"1.9.2",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var t=this;this.element.addClass("ui-selectable"),this.dragged=!1;var n;this.refresh=function(){n=e(t.options.filter,t.element[0]),n.addClass("ui-selectee"),n.each(function(){var t=e(this),n=t.offset();e.data(this,"selectable-item",{element:this,$element:t,left:n.left,top:n.top,right:n.left+t.outerWidth(),bottom:n.top+t.outerHeight(),startselected:!1,selected:t.hasClass("ui-selected"),selecting:t.hasClass("ui-selecting"),unselecting:t.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=n.addClass("ui-selectee"),this._mouseInit(),this.helper=e("<div class='ui-selectable-helper'></div>")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(t){var n=this;this.opos=[t.pageX,t.pageY];if(this.options.disabled)return;var r=this.options;this.selectees=e(r.filter,this.element[0]),this._trigger("start",t),e(r.appendTo).append(this.helper),this.helper.css({left:t.clientX,top:t.clientY,width:0,height:0}),r.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var r=e.data(this,"selectable-item");r.startselected=!0,!t.metaKey&&!t.ctrlKey&&(r.$element.removeClass("ui-selected"),r.selected=!1,r.$element.addClass("ui-unselecting"),r.unselecting=!0,n._trigger("unselecting",t,{unselecting:r.element}))}),e(t.target).parents().andSelf().each(function(){var r=e.data(this,"selectable-item");if(r){var i=!t.metaKey&&!t.ctrlKey||!r.$element.hasClass("ui-selected");return r.$element.removeClass(i?"ui-unselecting":"ui-selected").addClass(i?"ui-selecting":"ui-unselecting"),r.unselecting=!i,r.selecting=i,r.selected=i,i?n._trigger("selecting",t,{selecting:r.element}):n._trigger("unselecting",t,{unselecting:r.element}),!1}})},_mouseDrag:function(t){var n=this;this.dragged=!0;if(this.options.disabled)return;var r=this.options,i=this.opos[0],s=this.opos[1],o=t.pageX,u=t.pageY;if(i>o){var a=o;o=i,i=a}if(s>u){var a=u;u=s,s=a}return this.helper.css({left:i,top:s,width:o-i,height:u-s}),this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!a||a.element==n.element[0])return;var f=!1;r.tolerance=="touch"?f=!(a.left>o||a.right<i||a.top>u||a.bottom<s):r.tolerance=="fit"&&(f=a.left>i&&a.right<o&&a.top>s&&a.bottom<u),f?(a.selected&&(a.$element.removeClass("ui-selected"),a.selected=!1),a.unselecting&&(a.$element.removeClass("ui-unselecting"),a.unselecting=!1),a.selecting||(a.$element.addClass("ui-selecting"),a.selecting=!0,n._trigger("selecting",t,{selecting:a.element}))):(a.selecting&&((t.metaKey||t.ctrlKey)&&a.startselected?(a.$element.removeClass("ui-selecting"),a.selecting=!1,a.$element.addClass("ui-selected"),a.selected=!0):(a.$element.removeClass("ui-selecting"),a.selecting=!1,a.startselected&&(a.$element.addClass("ui-unselecting"),a.unselecting=!0),n._trigger("unselecting",t,{unselecting:a.element}))),a.selected&&!t.metaKey&&!t.ctrlKey&&!a.startselected&&(a.$element.removeClass("ui-selected"),a.selected=!1,a.$element.addClass("ui-unselecting"),a.unselecting=!0,n._trigger("unselecting",t,{unselecting:a.element})))}),!1},_mouseStop:function(t){var n=this;this.dragged=!1;var r=this.options;return e(".ui-unselecting",this.element[0]).each(function(){var r=e.data(this,"selectable-item");r.$element.removeClass("ui-unselecting"),r.unselecting=!1,r.startselected=!1,n._trigger("unselected",t,{unselected:r.element})}),e(".ui-selecting",this.element[0]).each(function(){var r=e.data(this,"selectable-item");r.$element.removeClass("ui-selecting").addClass("ui-selected"),r.selecting=!1,r.selected=!0,r.startselected=!0,n._trigger("selected",t,{selected:r.element})}),this._trigger("stop",t),this.helper.remove(),!1}})})(jQuery);(function(e,t){var n=5;e.widget("ui.slider",e.ui.mouse,{version:"1.9.2",widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null},_create:function(){var t,r,i=this.options,s=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),o="<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",u=[];this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"+(i.disabled?" ui-slider-disabled ui-disabled":"")),this.range=e([]),i.range&&(i.range===!0&&(i.values||(i.values=[this._valueMin(),this._valueMin()]),i.values.length&&i.values.length!==2&&(i.values=[i.values[0],i.values[0]])),this.range=e("<div></div>").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(i.range==="min"||i.range==="max"?" ui-slider-range-"+i.range:""))),r=i.values&&i.values.length||1;for(t=s.length;t<r;t++)u.push(o);this.handles=s.add(e(u.join("")).appendTo(this.element)),this.handle=this.handles.eq(0),this.handles.add(this.range).filter("a").click(function(e){e.preventDefault()}).mouseenter(function(){i.disabled||e(this).addClass("ui-state-hover")}).mouseleave(function(){e(this).removeClass("ui-state-hover")}).focus(function(){i.disabled?e(this).blur():(e(".ui-slider .ui-state-focus").removeClass("ui-state-focus"),e(this).addClass("ui-state-focus"))}).blur(function(){e(this).removeClass("ui-state-focus")}),this.handles.each(function(t){e(this).data("ui-slider-handle-index",t)}),this._on(this.handles,{keydown:function(t){var r,i,s,o,u=e(t.target).data("ui-slider-handle-index");switch(t.keyCode){case e.ui.keyCode.HOME:case e.ui.keyCode.END:case e.ui.keyCode.PAGE_UP:case e.ui.keyCode.PAGE_DOWN:case e.ui.keyCode.UP:case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:case e.ui.keyCode.LEFT:t.preventDefault();if(!this._keySliding){this._keySliding=!0,e(t.target).addClass("ui-state-active"),r=this._start(t,u);if(r===!1)return}}o=this.options.step,this.options.values&&this.options.values.length?i=s=this.values(u):i=s=this.value();switch(t.keyCode){case e.ui.keyCode.HOME:s=this._valueMin();break;case e.ui.keyCode.END:s=this._valueMax();break;case e.ui.keyCode.PAGE_UP:s=this._trimAlignValue(i+(this._valueMax()-this._valueMin())/n);break;case e.ui.keyCode.PAGE_DOWN:s=this._trimAlignValue(i-(this._valueMax()-this._valueMin())/n);break;case e.ui.keyCode.UP:case e.ui.keyCode.RIGHT:if(i===this._valueMax())return;s=this._trimAlignValue(i+o);break;case e.ui.keyCode.DOWN:case e.ui.keyCode.LEFT:if(i===this._valueMin())return;s=this._trimAlignValue(i-o)}this._slide(t,u,s)},keyup:function(t){var n=e(t.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(t,n),this._change(t,n),e(t.target).removeClass("ui-state-active"))}}),this._refreshValue(),this._animateOff=!1},_destroy:function(){this.handles.remove(),this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all"),this._mouseDestroy()},_mouseCapture:function(t){var n,r,i,s,o,u,a,f,l=this,c=this.options;return c.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),n={x:t.pageX,y:t.pageY},r=this._normValueFromMouse(n),i=this._valueMax()-this._valueMin()+1,this.handles.each(function(t){var n=Math.abs(r-l.values(t));i>n&&(i=n,s=e(this),o=t)}),c.range===!0&&this.values(1)===c.min&&(o+=1,s=e(this.handles[o])),u=this._start(t,o),u===!1?!1:(this._mouseSliding=!0,this._handleIndex=o,s.addClass("ui-state-active").focus(),a=s.offset(),f=!e(t.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=f?{left:0,top:0}:{left:t.pageX-a.left-s.width()/2,top:t.pageY-a.top-s.height()/2-(parseInt(s.css("borderTopWidth"),10)||0)-(parseInt(s.css("borderBottomWidth"),10)||0)+(parseInt(s.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(t,o,r),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(e){var t={x:e.pageX,y:e.pageY},n=this._normValueFromMouse(t);return this._slide(e,this._handleIndex,n),!1},_mouseStop:function(e){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(e,this._handleIndex),this._change(e,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(e){var t,n,r,i,s;return this.orientation==="horizontal"?(t=this.elementSize.width,n=e.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(t=this.elementSize.height,n=e.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),r=n/t,r>1&&(r=1),r<0&&(r=0),this.orientation==="vertical"&&(r=1-r),i=this._valueMax()-this._valueMin(),s=this._valueMin()+r*i,this._trimAlignValue(s)},_start:function(e,t){var n={handle:this.handles[t],value:this.value()};return this.options.values&&this.options.values.length&&(n.value=this.values(t),n.values=this.values()),this._trigger("start",e,n)},_slide:function(e,t,n){var r,i,s;this.options.values&&this.options.values.length?(r=this.values(t?0:1),this.options.values.length===2&&this.options.range===!0&&(t===0&&n>r||t===1&&n<r)&&(n=r),n!==this.values(t)&&(i=this.values(),i[t]=n,s=this._trigger("slide",e,{handle:this.handles[t],value:n,values:i}),r=this.values(t?0:1),s!==!1&&this.values(t,n,!0))):n!==this.value()&&(s=this._trigger("slide",e,{handle:this.handles[t],value:n}),s!==!1&&this.value(n))},_stop:function(e,t){var n={handle:this.handles[t],value:this.value()};this.options.values&&this.options.values.length&&(n.value=this.values(t),n.values=this.values()),this._trigger("stop",e,n)},_change:function(e,t){if(!this._keySliding&&!this._mouseSliding){var n={handle:this.handles[t],value:this.value()};this.options.values&&this.options.values.length&&(n.value=this.values(t),n.values=this.values()),this._trigger("change",e,n)}},value:function(e){if(arguments.length){this.options.value=this._trimAlignValue(e),this._refreshValue(),this._change(null,0);return}return this._value()},values:function(t,n){var r,i,s;if(arguments.length>1){this.options.values[t]=this._trimAlignValue(n),this._refreshValue(),this._change(null,t);return}if(!arguments.length)return this._values();if(!e.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(t):this.value();r=this.options.values,i=arguments[0];for(s=0;s<r.length;s+=1)r[s]=this._trimAlignValue(i[s]),this._change(null,s);this._refreshValue()},_setOption:function(t,n){var r,i=0;e.isArray(this.options.values)&&(i=this.options.values.length),e.Widget.prototype._setOption.apply(this,arguments);switch(t){case"disabled":n?(this.handles.filter(".ui-state-focus").blur(),this.handles.removeClass("ui-state-hover"),this.handles.prop("disabled",!0),this.element.addClass("ui-disabled")):(this.handles.prop("disabled",!1),this.element.removeClass("ui-disabled"));break;case"orientation":this._detectOrientation(),this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation),this._refreshValue();break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":this._animateOff=!0,this._refreshValue();for(r=0;r<i;r+=1)this._change(null,r);this._animateOff=!1;break;case"min":case"max":this._animateOff=!0,this._refreshValue(),this._animateOff=!1}},_value:function(){var e=this.options.value;return e=this._trimAlignValue(e),e},_values:function(e){var t,n,r;if(arguments.length)return t=this.options.values[e],t=this._trimAlignValue(t),t;n=this.options.values.slice();for(r=0;r<n.length;r+=1)n[r]=this._trimAlignValue(n[r]);return n},_trimAlignValue:function(e){if(e<=this._valueMin())return this._valueMin();if(e>=this._valueMax())return this._valueMax();var t=this.options.step>0?this.options.step:1,n=(e-this._valueMin())%t,r=e-n;return Math.abs(n)*2>=t&&(r+=n>0?t:-t),parseFloat(r.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var t,n,r,i,s,o=this.options.range,u=this.options,a=this,f=this._animateOff?!1:u.animate,l={};this.options.values&&this.options.values.length?this.handles.each(function(r){n=(a.values(r)-a._valueMin())/(a._valueMax()-a._valueMin())*100,l[a.orientation==="horizontal"?"left":"bottom"]=n+"%",e(this).stop(1,1)[f?"animate":"css"](l,u.animate),a.options.range===!0&&(a.orientation==="horizontal"?(r===0&&a.range.stop(1,1)[f?"animate":"css"]({left:n+"%"},u.animate),r===1&&a.range[f?"animate":"css"]({width:n-t+"%"},{queue:!1,duration:u.animate})):(r===0&&a.range.stop(1,1)[f?"animate":"css"]({bottom:n+"%"},u.animate),r===1&&a.range[f?"animate":"css"]({height:n-t+"%"},{queue:!1,duration:u.animate}))),t=n}):(r=this.value(),i=this._valueMin(),s=this._valueMax(),n=s!==i?(r-i)/(s-i)*100:0,l[this.orientation==="horizontal"?"left":"bottom"]=n+"%",this.handle.stop(1,1)[f?"animate":"css"](l,u.animate),o==="min"&&this.orientation==="horizontal"&&this.range.stop(1,1)[f?"animate":"css"]({width:n+"%"},u.animate),o==="max"&&this.orientation==="horizontal"&&this.range[f?"animate":"css"]({width:100-n+"%"},{queue:!1,duration:u.animate}),o==="min"&&this.orientation==="vertical"&&this.range.stop(1,1)[f?"animate":"css"]({height:n+"%"},u.animate),o==="max"&&this.orientation==="vertical"&&this.range[f?"animate":"css"]({height:100-n+"%"},{queue:!1,duration:u.animate}))}})})(jQuery);(function(e,t){e.widget("ui.sortable",e.ui.mouse,{version:"1.9.2",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3},_create:function(){var e=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?e.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var e=this.items.length-1;e>=0;e--)this.items[e].item.removeData(this.widgetName+"-item");return this},_setOption:function(t,n){t==="disabled"?(this.options[t]=n,this.widget().toggleClass("ui-sortable-disabled",!!n)):e.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(t,n){var r=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type=="static")return!1;this._refreshItems(t);var i=null,s=e(t.target).parents().each(function(){if(e.data(this,r.widgetName+"-item")==r)return i=e(this),!1});e.data(t.target,r.widgetName+"-item")==r&&(i=e(t.target));if(!i)return!1;if(this.options.handle&&!n){var o=!1;e(this.options.handle,i).find("*").andSelf().each(function(){this==t.target&&(o=!0)});if(!o)return!1}return this.currentItem=i,this._removeCurrentsFromItems(),!0},_mouseStart:function(t,n,r){var i=this.options;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!=this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),i.containment&&this._setContainment(),i.cursor&&(e("body").css("cursor")&&(this._storedCursor=e("body").css("cursor")),e("body").css("cursor",i.cursor)),i.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",i.opacity)),i.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",i.zIndex)),this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!r)for(var s=this.containers.length-1;s>=0;s--)this.containers[s]._trigger("activate",t,this._uiHash(this));return e.ui.ddmanager&&(e.ui.ddmanager.current=this),e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var n=this.options,r=!1;this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY<n.scrollSensitivity?this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop+n.scrollSpeed:t.pageY-this.overflowOffset.top<n.scrollSensitivity&&(this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop-n.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-t.pageX<n.scrollSensitivity?this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft+n.scrollSpeed:t.pageX-this.overflowOffset.left<n.scrollSensitivity&&(this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft-n.scrollSpeed)):(t.pageY-e(document).scrollTop()<n.scrollSensitivity?r=e(document).scrollTop(e(document).scrollTop()-n.scrollSpeed):e(window).height()-(t.pageY-e(document).scrollTop())<n.scrollSensitivity&&(r=e(document).scrollTop(e(document).scrollTop()+n.scrollSpeed)),t.pageX-e(document).scrollLeft()<n.scrollSensitivity?r=e(document).scrollLeft(e(document).scrollLeft()-n.scrollSpeed):e(window).width()-(t.pageX-e(document).scrollLeft())<n.scrollSensitivity&&(r=e(document).scrollLeft(e(document).scrollLeft()+n.scrollSpeed))),r!==!1&&e.ui.ddmanager&&!n.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(var i=this.items.length-1;i>=0;i--){var s=this.items[i],o=s.item[0],u=this._intersectsWithPointer(s);if(!u)continue;if(s.instance!==this.currentContainer)continue;if(o!=this.currentItem[0]&&this.placeholder[u==1?"next":"prev"]()[0]!=o&&!e.contains(this.placeholder[0],o)&&(this.options.type=="semi-dynamic"?!e.contains(this.element[0],o):!0)){this.direction=u==1?"down":"up";if(this.options.tolerance!="pointer"&&!this._intersectsWithSides(s))break;this._rearrange(t,s),this._trigger("change",t,this._uiHash());break}}return this._contactContainers(t),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,n){if(!t)return;e.ui.ddmanager&&!this.options.dropBehaviour&&e.ui.ddmanager.drop(this,t);if(this.options.revert){var r=this,i=this.placeholder.offset();this.reverting=!0,e(this.helper).animate({left:i.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:i.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){r._clear(t)})}else this._clear(t,n);return!1},cancel:function(){if(this.dragging){this._mouseUp({target:null}),this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var t=this.containers.length-1;t>=0;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),e.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?e(this.domPosition.prev).after(this.currentItem):e(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(t){var n=this._getItemsAsjQuery(t&&t.connected),r=[];return t=t||{},e(n).each(function(){var n=(e(t.item||this).attr(t.attribute||"id")||"").match(t.expression||/(.+)[-=_](.+)/);n&&r.push((t.key||n[1]+"[]")+"="+(t.key&&t.expression?n[1]:n[2]))}),!r.length&&t.key&&r.push(t.key+"="),r.join("&")},toArray:function(t){var n=this._getItemsAsjQuery(t&&t.connected),r=[];return t=t||{},n.each(function(){r.push(e(t.item||this).attr(t.attribute||"id")||"")}),r},_intersectsWith:function(e){var t=this.positionAbs.left,n=t+this.helperProportions.width,r=this.positionAbs.top,i=r+this.helperProportions.height,s=e.left,o=s+e.width,u=e.top,a=u+e.height,f=this.offset.click.top,l=this.offset.click.left,c=r+f>u&&r+f<a&&t+l>s&&t+l<o;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers||this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>e[this.floating?"width":"height"]?c:s<t+this.helperProportions.width/2&&n-this.helperProportions.width/2<o&&u<r+this.helperProportions.height/2&&i-this.helperProportions.height/2<a},_intersectsWithPointer:function(t){var n=this.options.axis==="x"||e.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,t.top,t.height),r=this.options.axis==="y"||e.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,t.left,t.width),i=n&&r,s=this._getDragVerticalDirection(),o=this._getDragHorizontalDirection();return i?this.floating?o&&o=="right"||s=="down"?2:1:s&&(s=="down"?2:1):!1},_intersectsWithSides:function(t){var n=e.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),r=e.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),i=this._getDragVerticalDirection(),s=this._getDragHorizontalDirection();return this.floating&&s?s=="right"&&r||s=="left"&&!r:i&&(i=="down"&&n||i=="up"&&!n)},_getDragVerticalDirection:function(){var e=this.positionAbs.top-this.lastPositionAbs.top;return e!=0&&(e>0?"down":"up")},_getDragHorizontalDirection:function(){var e=this.positionAbs.left-this.lastPositionAbs.left;return e!=0&&(e>0?"right":"left")},refresh:function(e){return this._refreshItems(e),this.refreshPositions(),this},_connectWith:function(){var e=this.options;return e.connectWith.constructor==String?[e.connectWith]:e.connectWith},_getItemsAsjQuery:function(t){var n=[],r=[],i=this._connectWith();if(i&&t)for(var s=i.length-1;s>=0;s--){var o=e(i[s]);for(var u=o.length-1;u>=0;u--){var a=e.data(o[u],this.widgetName);a&&a!=this&&!a.options.disabled&&r.push([e.isFunction(a.options.items)?a.options.items.call(a.element):e(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a])}}r.push([e.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):e(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var s=r.length-1;s>=0;s--)r[s][0].each(function(){n.push(this)});return e(n)},_removeCurrentsFromItems:function(){var t=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=e.grep(this.items,function(e){for(var n=0;n<t.length;n++)if(t[n]==e.item[0])return!1;return!0})},_refreshItems:function(t){this.items=[],this.containers=[this];var n=this.items,r=[[e.isFunction(this.options.items)?this.options.items.call(this.element[0],t,{item:this.currentItem}):e(this.options.items,this.element),this]],i=this._connectWith();if(i&&this.ready)for(var s=i.length-1;s>=0;s--){var o=e(i[s]);for(var u=o.length-1;u>=0;u--){var a=e.data(o[u],this.widgetName);a&&a!=this&&!a.options.disabled&&(r.push([e.isFunction(a.options.items)?a.options.items.call(a.element[0],t,{item:this.currentItem}):e(a.options.items,a.element),a]),this.containers.push(a))}}for(var s=r.length-1;s>=0;s--){var f=r[s][1],l=r[s][0];for(var u=0,c=l.length;u<c;u++){var h=e(l[u]);h.data(this.widgetName+"-item",f),n.push({item:h,instance:f,width:0,height:0,left:0,top:0})}}},refreshPositions:function(t){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());for(var n=this.items.length-1;n>=0;n--){var r=this.items[n];if(r.instance!=this.currentContainer&&this.currentContainer&&r.item[0]!=this.currentItem[0])continue;var i=this.options.toleranceElement?e(this.options.toleranceElement,r.item):r.item;t||(r.width=i.outerWidth(),r.height=i.outerHeight());var s=i.offset();r.left=s.left,r.top=s.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(var n=this.containers.length-1;n>=0;n--){var s=this.containers[n].element.offset();this.containers[n].containerCache.left=s.left,this.containers[n].containerCache.top=s.top,this.containers[n].containerCache.width=this.containers[n].element.outerWidth(),this.containers[n].containerCache.height=this.containers[n].element.outerHeight()}return this},_createPlaceholder:function(t){t=t||this;var n=t.options;if(!n.placeholder||n.placeholder.constructor==String){var r=n.placeholder;n.placeholder={element:function(){var n=e(document.createElement(t.currentItem[0].nodeName)).addClass(r||t.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];return r||(n.style.visibility="hidden"),n},update:function(e,i){if(r&&!n.forcePlaceholderSize)return;i.height()||i.height(t.currentItem.innerHeight()-parseInt(t.currentItem.css("paddingTop")||0,10)-parseInt(t.currentItem.css("paddingBottom")||0,10)),i.width()||i.width(t.currentItem.innerWidth()-parseInt(t.currentItem.css("paddingLeft")||0,10)-parseInt(t.currentItem.css("paddingRight")||0,10))}}}t.placeholder=e(n.placeholder.element.call(t.element,t.currentItem)),t.currentItem.after(t.placeholder),n.placeholder.update(t,t.placeholder)},_contactContainers:function(t){var n=null,r=null;for(var i=this.containers.length-1;i>=0;i--){if(e.contains(this.currentItem[0],this.containers[i].element[0]))continue;if(this._intersectsWith(this.containers[i].containerCache)){if(n&&e.contains(this.containers[i].element[0],n.element[0]))continue;n=this.containers[i],r=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",t,this._uiHash(this)),this.containers[i].containerCache.over=0)}if(!n)return;if(this.containers.length===1)this.containers[r]._trigger("over",t,this._uiHash(this)),this.containers[r].containerCache.over=1;else{var s=1e4,o=null,u=this.containers[r].floating?"left":"top",a=this.containers[r].floating?"width":"height",f=this.positionAbs[u]+this.offset.click[u];for(var l=this.items.length-1;l>=0;l--){if(!e.contains(this.containers[r].element[0],this.items[l].item[0]))continue;if(this.items[l].item[0]==this.currentItem[0])continue;var c=this.items[l].item.offset()[u],h=!1;Math.abs(c-f)>Math.abs(c+this.items[l][a]-f)&&(h=!0,c+=this.items[l][a]),Math.abs(c-f)<s&&(s=Math.abs(c-f),o=this.items[l],this.direction=h?"up":"down")}if(!o&&!this.options.dropOnEmpty)return;this.currentContainer=this.containers[r],o?this._rearrange(t,o,null,!0):this._rearrange(t,null,this.containers[r].element,!0),this._trigger("change",t,this._uiHash()),this.containers[r]._trigger("change",t,this._uiHash(this)),this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[r]._trigger("over",t,this._uiHash(this)),this.containers[r].containerCache.over=1}},_createHelper:function(t){var n=this.options,r=e.isFunction(n.helper)?e(n.helper.apply(this.element[0],[t,this.currentItem])):n.helper=="clone"?this.currentItem.clone():this.currentItem;return r.parents("body").length||e(n.appendTo!="parent"?n.appendTo:this.currentItem[0].parentNode)[0].appendChild(r[0]),r[0]==this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(r[0].style.width==""||n.forceHelperSize)&&r.width(this.currentItem.width()),(r[0].style.height==""||n.forceHelperSize)&&r.height(this.currentItem.height()),r},_adjustOffsetFromHelper:function(t){typeof t=="string"&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&e.ui.ie)t={top:0,left:0};return{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var e=this.currentItem.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t=this.options;t.containment=="parent"&&(t.containment=this.helper[0].parentNode);if(t.containment=="document"||t.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,e(t.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(e(t.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(t.containment)){var n=e(t.containment)[0],r=e(t.containment).offset(),i=e(n).css("overflow")!="hidden";this.containment=[r.left+(parseInt(e(n).css("borderLeftWidth"),10)||0)+(parseInt(e(n).css("paddingLeft"),10)||0)-this.margins.left,r.top+(parseInt(e(n).css("borderTopWidth"),10)||0)+(parseInt(e(n).css("paddingTop"),10)||0)-this.margins.top,r.left+(i?Math.max(n.scrollWidth,n.offsetWidth):n.offsetWidth)-(parseInt(e(n).css("borderLeftWidth"),10)||0)-(parseInt(e(n).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,r.top+(i?Math.max(n.scrollHeight,n.offsetHeight):n.offsetHeight)-(parseInt(e(n).css("borderTopWidth"),10)||0)-(parseInt(e(n).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(t,n){n||(n=this.position);var r=t=="absolute"?1:-1,i=this.options,s=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(s[0].tagName);return{top:n.top+this.offset.relative.top*r+this.offset.parent.top*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():o?0:s.scrollTop())*r,left:n.left+this.offset.relative.left*r+this.offset.parent.left*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():o?0:s.scrollLeft())*r}},_generatePosition:function(t){var n=this.options,r=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,i=/(html|body)/i.test(r[0].tagName);this.cssPosition=="relative"&&(this.scrollParent[0]==document||this.scrollParent[0]==this.offsetParent[0])&&(this.offset.relative=this._getRelativeOffset());var s=t.pageX,o=t.pageY;if(this.originalPosition){this.containment&&(t.pageX-this.offset.click.left<this.containment[0]&&(s=this.containment[0]+this.offset.click.left),t.pageY-this.offset.click.top<this.containment[1]&&(o=this.containment[1]+this.offset.click.top),t.pageX-this.offset.click.left>this.containment[2]&&(s=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(o=this.containment[3]+this.offset.click.top));if(n.grid){var u=this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1];o=this.containment?u-this.offset.click.top<this.containment[1]||u-this.offset.click.top>this.containment[3]?u-this.offset.click.top<this.containment[1]?u+n.grid[1]:u-n.grid[1]:u:u;var a=this.originalPageX+Math.round((s-this.originalPageX)/n.grid[0])*n.grid[0];s=this.containment?a-this.offset.click.left<this.containment[0]||a-this.offset.click.left>this.containment[2]?a-this.offset.click.left<this.containment[0]?a+n.grid[0]:a-n.grid[0]:a:a}}return{top:o-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():i?0:r.scrollTop()),left:s-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():i?0:r.scrollLeft())}},_rearrange:function(e,t,n,r){n?n[0].appendChild(this.placeholder[0]):t.item[0].parentNode.insertBefore(this.placeholder[0],this.direction=="down"?t.item[0]:t.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var i=this.counter;this._delay(function(){i==this.counter&&this.refreshPositions(!r)})},_clear:function(t,n){this.reverting=!1;var r=[];!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var i in this._storedCSS)if(this._storedCSS[i]=="auto"||this._storedCSS[i]=="static")this._storedCSS[i]="";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!n&&r.push(function(e){this._trigger("receive",e,this._uiHash(this.fromOutside))}),(this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!n&&r.push(function(e){this._trigger("update",e,this._uiHash())}),this!==this.currentContainer&&(n||(r.push(function(e){this._trigger("remove",e,this._uiHash())}),r.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),r.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer))));for(var i=this.containers.length-1;i>=0;i--)n||r.push(function(e){return function(t){e._trigger("deactivate",t,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over&&(r.push(function(e){return function(t){e._trigger("out",t,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over=0);this._storedCursor&&e("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!n){this._trigger("beforeStop",t,this._uiHash());for(var i=0;i<r.length;i++)r[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!1}n||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!=this.currentItem[0]&&this.helper.remove(),this.helper=null;if(!n){for(var i=0;i<r.length;i++)r[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!0},_trigger:function(){e.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(t){var n=t||this;return{helper:n.helper,placeholder:n.placeholder||e([]),position:n.position,originalPosition:n.originalPosition,offset:n.positionAbs,item:n.currentItem,sender:t?t.element:null}}})})(jQuery);(function(e){function t(e){return function(){var t=this.element.val();e.apply(this,arguments),this._refresh(),t!==this.element.val()&&this._trigger("change")}}e.widget("ui.spinner",{version:"1.9.2",defaultElement:"<input>",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var t={},n=this.element;return e.each(["min","max","step"],function(e,r){var i=n.attr(r);i!==undefined&&i.length&&(t[r]=i)}),t},_events:{keydown:function(e){this._start(e)&&this._keydown(e)&&e.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(e){if(this.cancelBlur){delete this.cancelBlur;return}this._refresh(),this.previous!==this.element.val()&&this._trigger("change",e)},mousewheel:function(e,t){if(!t)return;if(!this.spinning&&!this._start(e))return!1;this._spin((t>0?1:-1)*this.options.step,e),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(e)},100),e.preventDefault()},"mousedown .ui-spinner-button":function(t){function r(){var e=this.element[0]===this.document[0].activeElement;e||(this.element.focus(),this.previous=n,this._delay(function(){this.previous=n}))}var n;n=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),t.preventDefault(),r.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,r.call(this)});if(this._start(t)===!1)return;this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(t){if(!e(t.currentTarget).hasClass("ui-state-active"))return;if(this._start(t)===!1)return!1;this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var e=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this.element.attr("role","spinbutton"),this.buttons=e.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(e.height()*.5)&&e.height()>0&&e.height(e.height()),this.options.disabled&&this.disable()},_keydown:function(t){var n=this.options,r=e.ui.keyCode;switch(t.keyCode){case r.UP:return this._repeat(null,1,t),!0;case r.DOWN:return this._repeat(null,-1,t),!0;case r.PAGE_UP:return this._repeat(null,n.page,t),!0;case r.PAGE_DOWN:return this._repeat(null,-n.page,t),!0}return!1},_uiSpinnerHtml:function(){return"<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"},_buttonHtml:function(){return"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'><span class='ui-icon "+this.options.icons.up+"'>▲</span>"+"</a>"+"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>"+"<span class='ui-icon "+this.options.icons.down+"'>▼</span>"+"</a>"},_start:function(e){return!this.spinning&&this._trigger("start",e)===!1?!1:(this.counter||(this.counter=1),this.spinning=!0,!0)},_repeat:function(e,t,n){e=e||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,t,n)},e),this._spin(t*this.options.step,n)},_spin:function(e,t){var n=this.value()||0;this.counter||(this.counter=1),n=this._adjustValue(n+e*this._increment(this.counter));if(!this.spinning||this._trigger("spin",t,{value:n})!==!1)this._value(n),this.counter++},_increment:function(t){var n=this.options.incremental;return n?e.isFunction(n)?n(t):Math.floor(t*t*t/5e4-t*t/500+17*t/200+1):1},_precision:function(){var e=this._precisionOf(this.options.step);return this.options.min!==null&&(e=Math.max(e,this._precisionOf(this.options.min))),e},_precisionOf:function(e){var t=e.toString(),n=t.indexOf(".");return n===-1?0:t.length-n-1},_adjustValue:function(e){var t,n,r=this.options;return t=r.min!==null?r.min:0,n=e-t,n=Math.round(n/r.step)*r.step,e=t+n,e=parseFloat(e.toFixed(this._precision())),r.max!==null&&e>r.max?r.max:r.min!==null&&e<r.min?r.min:e},_stop:function(e){if(!this.spinning)return;clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",e)},_setOption:function(e,t){if(e==="culture"||e==="numberFormat"){var n=this._parse(this.element.val());this.options[e]=t,this.element.val(this._format(n));return}(e==="max"||e==="min"||e==="step")&&typeof t=="string"&&(t=this._parse(t)),this._super(e,t),e==="disabled"&&(t?(this.element.prop("disabled",!0),this.buttons.button("disable")):(this.element.prop("disabled",!1),this.buttons.button("enable")))},_setOptions:t(function(e){this._super(e),this._value(this.element.val())}),_parse:function(e){return typeof e=="string"&&e!==""&&(e=window.Globalize&&this.options.numberFormat?Globalize.parseFloat(e,10,this.options.culture):+e),e===""||isNaN(e)?null:e},_format:function(e){return e===""?"":window.Globalize&&this.options.numberFormat?Globalize.format(e,this.options.numberFormat,this.options.culture):e},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},_value:function(e,t){var n;e!==""&&(n=this._parse(e),n!==null&&(t||(n=this._adjustValue(n)),e=this._format(n))),this.element.val(e),this._refresh()},_destroy:function(){this.element.removeClass("ui-spinner-input").prop("disabled",!1).removeAttr("autocomplete").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:t(function(e){this._stepUp(e)}),_stepUp:function(e){this._spin((e||1)*this.options.step)},stepDown:t(function(e){this._stepDown(e)}),_stepDown:function(e){this._spin((e||1)*-this.options.step)},pageUp:t(function(e){this._stepUp((e||1)*this.options.page)}),pageDown:t(function(e){this._stepDown((e||1)*this.options.page)}),value:function(e){if(!arguments.length)return this._parse(this.element.val());t(this._value).call(this,e)},widget:function(){return this.uiSpinner}})})(jQuery);(function(e,t){function i(){return++n}function s(e){return e.hash.length>1&&e.href.replace(r,"")===location.href.replace(r,"").replace(/\s/g,"%20")}var n=0,r=/#.*$/;e.widget("ui.tabs",{version:"1.9.2",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var t=this,n=this.options,r=n.active,i=location.hash.substring(1);this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",n.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(t){e(this).is(".ui-state-disabled")&&t.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){e(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this._processTabs();if(r===null){i&&this.tabs.each(function(t,n){if(e(n).attr("aria-controls")===i)return r=t,!1}),r===null&&(r=this.tabs.index(this.tabs.filter(".ui-tabs-active")));if(r===null||r===-1)r=this.tabs.length?0:!1}r!==!1&&(r=this.tabs.index(this.tabs.eq(r)),r===-1&&(r=n.collapsible?!1:0)),n.active=r,!n.collapsible&&n.active===!1&&this.anchors.length&&(n.active=0),e.isArray(n.disabled)&&(n.disabled=e.unique(n.disabled.concat(e.map(this.tabs.filter(".ui-state-disabled"),function(e){return t.tabs.index(e)}))).sort()),this.options.active!==!1&&this.anchors.length?this.active=this._findActive(this.options.active):this.active=e(),this._refresh(),this.active.length&&this.load(n.active)},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):e()}},_tabKeydown:function(t){var n=e(this.document[0].activeElement).closest("li"),r=this.tabs.index(n),i=!0;if(this._handlePageNav(t))return;switch(t.keyCode){case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:r++;break;case e.ui.keyCode.UP:case e.ui.keyCode.LEFT:i=!1,r--;break;case e.ui.keyCode.END:r=this.anchors.length-1;break;case e.ui.keyCode.HOME:r=0;break;case e.ui.keyCode.SPACE:t.preventDefault(),clearTimeout(this.activating),this._activate(r);return;case e.ui.keyCode.ENTER:t.preventDefault(),clearTimeout(this.activating),this._activate(r===this.options.active?!1:r);return;default:return}t.preventDefault(),clearTimeout(this.activating),r=this._focusNextTab(r,i),t.ctrlKey||(n.attr("aria-selected","false"),this.tabs.eq(r).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",r)},this.delay))},_panelKeydown:function(t){if(this._handlePageNav(t))return;t.ctrlKey&&t.keyCode===e.ui.keyCode.UP&&(t.preventDefault(),this.active.focus())},_handlePageNav:function(t){if(t.altKey&&t.keyCode===e.ui.keyCode.PAGE_UP)return this._activate(this._focusNextTab(this.options.active-1,!1)),!0;if(t.altKey&&t.keyCode===e.ui.keyCode.PAGE_DOWN)return this._activate(this._focusNextTab(this.options.active+1,!0)),!0},_findNextTab:function(t,n){function i(){return t>r&&(t=0),t<0&&(t=r),t}var r=this.tabs.length-1;while(e.inArray(i(),this.options.disabled)!==-1)t=n?t+1:t-1;return t},_focusNextTab:function(e,t){return e=this._findNextTab(e,t),this.tabs.eq(e).focus(),e},_setOption:function(e,t){if(e==="active"){this._activate(t);return}if(e==="disabled"){this._setupDisabled(t);return}this._super(e,t),e==="collapsible"&&(this.element.toggleClass("ui-tabs-collapsible",t),!t&&this.options.active===!1&&this._activate(0)),e==="event"&&this._setupEvents(t),e==="heightStyle"&&this._setupHeightStyle(t)},_tabId:function(e){return e.attr("aria-controls")||"ui-tabs-"+i()},_sanitizeSelector:function(e){return e?e.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t=this.options,n=this.tablist.children(":has(a[href])");t.disabled=e.map(n.filter(".ui-state-disabled"),function(e){return n.index(e)}),this._processTabs(),t.active===!1||!this.anchors.length?(t.active=!1,this.active=e()):this.active.length&&!e.contains(this.tablist[0],this.active[0])?this.tabs.length===t.disabled.length?(t.active=!1,this.active=e()):this._activate(this._findNextTab(Math.max(0,t.active-1),!1)):t.active=this.tabs.index(this.active),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-expanded":"false","aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-expanded":"true","aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var t=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist"),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return e("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=e(),this.anchors.each(function(n,r){var i,o,u,a=e(r).uniqueId().attr("id"),f=e(r).closest("li"),l=f.attr("aria-controls");s(r)?(i=r.hash,o=t.element.find(t._sanitizeSelector(i))):(u=t._tabId(f),i="#"+u,o=t.element.find(i),o.length||(o=t._createPanel(u),o.insertAfter(t.panels[n-1]||t.tablist)),o.attr("aria-live","polite")),o.length&&(t.panels=t.panels.add(o)),l&&f.data("ui-tabs-aria-controls",l),f.attr({"aria-controls":i.substring(1),"aria-labelledby":a}),o.attr("aria-labelledby",a)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.element.find("ol,ul").eq(0)},_createPanel:function(t){return e("<div>").attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(t){e.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1);for(var n=0,r;r=this.tabs[n];n++)t===!0||e.inArray(n,t)!==-1?e(r).addClass("ui-state-disabled").attr("aria-disabled","true"):e(r).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=t},_setupEvents:function(t){var n={click:function(e){e.preventDefault()}};t&&e.each(t.split(" "),function(e,t){n[t]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(this.anchors,n),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var n,r,i=this.element.parent();t==="fill"?(e.support.minHeight||(r=i.css("overflow"),i.css("overflow","hidden")),n=i.height(),this.element.siblings(":visible").each(function(){var t=e(this),r=t.css("position");if(r==="absolute"||r==="fixed")return;n-=t.outerHeight(!0)}),r&&i.css("overflow",r),this.element.children().not(this.panels).each(function(){n-=e(this).outerHeight(!0)}),this.panels.each(function(){e(this).height(Math.max(0,n-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):t==="auto"&&(n=0,this.panels.each(function(){n=Math.max(n,e(this).height("").height())}).height(n))},_eventHandler:function(t){var n=this.options,r=this.active,i=e(t.currentTarget),s=i.closest("li"),o=s[0]===r[0],u=o&&n.collapsible,a=u?e():this._getPanelForTab(s),f=r.length?this._getPanelForTab(r):e(),l={oldTab:r,oldPanel:f,newTab:u?e():s,newPanel:a};t.preventDefault();if(s.hasClass("ui-state-disabled")||s.hasClass("ui-tabs-loading")||this.running||o&&!n.collapsible||this._trigger("beforeActivate",t,l)===!1)return;n.active=u?!1:this.tabs.index(s),this.active=o?e():s,this.xhr&&this.xhr.abort(),!f.length&&!a.length&&e.error("jQuery UI Tabs: Mismatching fragment identifier."),a.length&&this.load(this.tabs.index(s),t),this._toggle(t,l)},_toggle:function(t,n){function o(){r.running=!1,r._trigger("activate",t,n)}function u(){n.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),i.length&&r.options.show?r._show(i,r.options.show,o):(i.show(),o())}var r=this,i=n.newPanel,s=n.oldPanel;this.running=!0,s.length&&this.options.hide?this._hide(s,this.options.hide,function(){n.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),u()}):(n.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),s.hide(),u()),s.attr({"aria-expanded":"false","aria-hidden":"true"}),n.oldTab.attr("aria-selected","false"),i.length&&s.length?n.oldTab.attr("tabIndex",-1):i.length&&this.tabs.filter(function(){return e(this).attr("tabIndex")===0}).attr("tabIndex",-1),i.attr({"aria-expanded":"true","aria-hidden":"false"}),n.newTab.attr({"aria-selected":"true",tabIndex:0})},_activate:function(t){var n,r=this._findActive(t);if(r[0]===this.active[0])return;r.length||(r=this.active),n=r.find(".ui-tabs-anchor")[0],this._eventHandler({target:n,currentTarget:n,preventDefault:e.noop})},_findActive:function(t){return t===!1?e():this.tabs.eq(t)},_getIndex:function(e){return typeof e=="string"&&(e=this.anchors.index(this.anchors.filter("[href$='"+e+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeData("href.tabs").removeData("load.tabs").removeUniqueId(),this.tabs.add(this.panels).each(function(){e.data(this,"ui-tabs-destroy")?e(this).remove():e(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var t=e(this),n=t.data("ui-tabs-aria-controls");n?t.attr("aria-controls",n):t.removeAttr("aria-controls")}),this.panels.show(),this.options.heightStyle!=="content"&&this.panels.css("height","")},enable:function(n){var r=this.options.disabled;if(r===!1)return;n===t?r=!1:(n=this._getIndex(n),e.isArray(r)?r=e.map(r,function(e){return e!==n?e:null}):r=e.map(this.tabs,function(e,t){return t!==n?t:null})),this._setupDisabled(r)},disable:function(n){var r=this.options.disabled;if(r===!0)return;if(n===t)r=!0;else{n=this._getIndex(n);if(e.inArray(n,r)!==-1)return;e.isArray(r)?r=e.merge([n],r).sort():r=[n]}this._setupDisabled(r)},load:function(t,n){t=this._getIndex(t);var r=this,i=this.tabs.eq(t),o=i.find(".ui-tabs-anchor"),u=this._getPanelForTab(i),a={tab:i,panel:u};if(s(o[0]))return;this.xhr=e.ajax(this._ajaxSettings(o,n,a)),this.xhr&&this.xhr.statusText!=="canceled"&&(i.addClass("ui-tabs-loading"),u.attr("aria-busy","true"),this.xhr.success(function(e){setTimeout(function(){u.html(e),r._trigger("load",n,a)},1)}).complete(function(e,t){setTimeout(function(){t==="abort"&&r.panels.stop(!1,!0),i.removeClass("ui-tabs-loading"),u.removeAttr("aria-busy"),e===r.xhr&&delete r.xhr},1)}))},_ajaxSettings:function(t,n,r){var i=this;return{url:t.attr("href"),beforeSend:function(t,s){return i._trigger("beforeLoad",n,e.extend({jqXHR:t,ajaxSettings:s},r))}}},_getPanelForTab:function(t){var n=e(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+n))}}),e.uiBackCompat!==!1&&(e.ui.tabs.prototype._ui=function(e,t){return{tab:e,panel:t,index:this.anchors.index(e)}},e.widget("ui.tabs",e.ui.tabs,{url:function(e,t){this.anchors.eq(e).attr("href",t)}}),e.widget("ui.tabs",e.ui.tabs,{options:{ajaxOptions:null,cache:!1},_create:function(){this._super();var t=this;this._on({tabsbeforeload:function(n,r){if(e.data(r.tab[0],"cache.tabs")){n.preventDefault();return}r.jqXHR.success(function(){t.options.cache&&e.data(r.tab[0],"cache.tabs",!0)})}})},_ajaxSettings:function(t,n,r){var i=this.options.ajaxOptions;return e.extend({},i,{error:function(e,t){try{i.error(e,t,r.tab.closest("li").index(),r.tab[0])}catch(n){}}},this._superApply(arguments))},_setOption:function(e,t){e==="cache"&&t===!1&&this.anchors.removeData("cache.tabs"),this._super(e,t)},_destroy:function(){this.anchors.removeData("cache.tabs"),this._super()},url:function(e){this.anchors.eq(e).removeData("cache.tabs"),this._superApply(arguments)}}),e.widget("ui.tabs",e.ui.tabs,{abort:function(){this.xhr&&this.xhr.abort()}}),e.widget("ui.tabs",e.ui.tabs,{options:{spinner:"<em>Loading…</em>"},_create:function(){this._super(),this._on({tabsbeforeload:function(e,t){if(e.target!==this.element[0]||!this.options.spinner)return;var n=t.tab.find("span"),r=n.html();n.html(this.options.spinner),t.jqXHR.complete(function(){n.html(r)})}})}}),e.widget("ui.tabs",e.ui.tabs,{options:{enable:null,disable:null},enable:function(t){var n=this.options,r;if(t&&n.disabled===!0||e.isArray(n.disabled)&&e.inArray(t,n.disabled)!==-1)r=!0;this._superApply(arguments),r&&this._trigger("enable",null,this._ui(this.anchors[t],this.panels[t]))},disable:function(t){var n=this.options,r;if(t&&n.disabled===!1||e.isArray(n.disabled)&&e.inArray(t,n.disabled)===-1)r=!0;this._superApply(arguments),r&&this._trigger("disable",null,this._ui(this.anchors[t],this.panels[t]))}}),e.widget("ui.tabs",e.ui.tabs,{options:{add:null,remove:null,tabTemplate:"<li><a href='#{href}'><span>#{label}</span></a></li>"},add:function(n,r,i){i===t&&(i=this.anchors.length);var s,o,u=this.options,a=e(u.tabTemplate.replace(/#\{href\}/g,n).replace(/#\{label\}/g,r)),f=n.indexOf("#")?this._tabId(a):n.replace("#","");return a.addClass("ui-state-default ui-corner-top").data("ui-tabs-destroy",!0),a.attr("aria-controls",f),s=i>=this.tabs.length,o=this.element.find("#"+f),o.length||(o=this._createPanel(f),s?i>0?o.insertAfter(this.panels.eq(-1)):o.appendTo(this.element):o.insertBefore(this.panels[i])),o.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").hide(),s?a.appendTo(this.tablist):a.insertBefore(this.tabs[i]),u.disabled=e.map(u.disabled,function(e){return e>=i?++e:e}),this.refresh(),this.tabs.length===1&&u.active===!1&&this.option("active",0),this._trigger("add",null,this._ui(this.anchors[i],this.panels[i])),this},remove:function(t){t=this._getIndex(t);var n=this.options,r=this.tabs.eq(t).remove(),i=this._getPanelForTab(r).remove();return r.hasClass("ui-tabs-active")&&this.anchors.length>2&&this._activate(t+(t+1<this.anchors.length?1:-1)),n.disabled=e.map(e.grep(n.disabled,function(e){return e!==t}),function(e){return e>=t?--e:e}),this.refresh(),this._trigger("remove",null,this._ui(r.find("a")[0],i[0])),this}}),e.widget("ui.tabs",e.ui.tabs,{length:function(){return this.anchors.length}}),e.widget("ui.tabs",e.ui.tabs,{options:{idPrefix:"ui-tabs-"},_tabId:function(t){var n=t.is("li")?t.find("a[href]"):t;return n=n[0],e(n).closest("li").attr("aria-controls")||n.title&&n.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF\-]/g,"")||this.options.idPrefix+i()}}),e.widget("ui.tabs",e.ui.tabs,{options:{panelTemplate:"<div></div>"},_createPanel:function(t){return e(this.options.panelTemplate).attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)}}),e.widget("ui.tabs",e.ui.tabs,{_create:function(){var e=this.options;e.active===null&&e.selected!==t&&(e.active=e.selected===-1?!1:e.selected),this._super(),e.selected=e.active,e.selected===!1&&(e.selected=-1)},_setOption:function(e,t){if(e!=="selected")return this._super(e,t);var n=this.options;this._super("active",t===-1?!1:t),n.selected=n.active,n.selected===!1&&(n.selected=-1)},_eventHandler:function(){this._superApply(arguments),this.options.selected=this.options.active,this.options.selected===!1&&(this.options.selected=-1)}}),e.widget("ui.tabs",e.ui.tabs,{options:{show:null,select:null},_create:function(){this._super(),this.options.active!==!1&&this._trigger("show",null,this._ui(this.active.find(".ui-tabs-anchor")[0],this._getPanelForTab(this.active)[0]))},_trigger:function(e,t,n){var r,i,s=this._superApply(arguments);return s?(e==="beforeActivate"?(r=n.newTab.length?n.newTab:n.oldTab,i=n.newPanel.length?n.newPanel:n.oldPanel,s=this._super("select",t,{tab:r.find(".ui-tabs-anchor")[0],panel:i[0],index:r.closest("li").index()})):e==="activate"&&n.newTab.length&&(s=this._super("show",t,{tab:n.newTab.find(".ui-tabs-anchor")[0],panel:n.newPanel[0],index:n.newTab.closest("li").index()})),s):!1}}),e.widget("ui.tabs",e.ui.tabs,{select:function(e){e=this._getIndex(e);if(e===-1){if(!this.options.collapsible||this.options.selected===-1)return;e=this.options.selected}this.anchors.eq(e).trigger(this.options.event+this.eventNamespace)}}),function(){var t=0;e.widget("ui.tabs",e.ui.tabs,{options:{cookie:null},_create:function(){var e=this.options,t;e.active==null&&e.cookie&&(t=parseInt(this._cookie(),10),t===-1&&(t=!1),e.active=t),this._super()},_cookie:function(n){var r=[this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+ ++t)];return arguments.length&&(r.push(n===!1?-1:n),r.push(this.options.cookie)),e.cookie.apply(null,r)},_refresh:function(){this._super(),this.options.cookie&&this._cookie(this.options.active,this.options.cookie)},_eventHandler:function(){this._superApply(arguments),this.options.cookie&&this._cookie(this.options.active,this.options.cookie)},_destroy:function(){this._super(),this.options.cookie&&this._cookie(null,this.options.cookie)}})}(),e.widget("ui.tabs",e.ui.tabs,{_trigger:function(t,n,r){var i=e.extend({},r);return t==="load"&&(i.panel=i.panel[0],i.tab=i.tab.find(".ui-tabs-anchor")[0]),this._super(t,n,i)}}),e.widget("ui.tabs",e.ui.tabs,{options:{fx:null},_getFx:function(){var t,n,r=this.options.fx;return r&&(e.isArray(r)?(t=r[0],n=r[1]):t=n=r),r?{show:n,hide:t}:null},_toggle:function(e,t){function o(){n.running=!1,n._trigger("activate",e,t)}function u(){t.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),r.length&&s.show?r.animate(s.show,s.show.duration,function(){o()}):(r.show(),o())}var n=this,r=t.newPanel,i=t.oldPanel,s=this._getFx();if(!s)return this._super(e,t);n.running=!0,i.length&&s.hide?i.animate(s.hide,s.hide.duration,function(){t.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),u()}):(t.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),i.hide(),u())}}))})(jQuery);(function(e){function n(t,n){var r=(t.attr("aria-describedby")||"").split(/\s+/);r.push(n),t.data("ui-tooltip-id",n).attr("aria-describedby",e.trim(r.join(" ")))}function r(t){var n=t.data("ui-tooltip-id"),r=(t.attr("aria-describedby")||"").split(/\s+/),i=e.inArray(n,r);i!==-1&&r.splice(i,1),t.removeData("ui-tooltip-id"),r=e.trim(r.join(" ")),r?t.attr("aria-describedby",r):t.removeAttr("aria-describedby")}var t=0;e.widget("ui.tooltip",{version:"1.9.2",options:{content:function(){return e(this).attr("title")},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.options.disabled&&this._disable()},_setOption:function(t,n){var r=this;if(t==="disabled"){this[n?"_disable":"_enable"](),this.options[t]=n;return}this._super(t,n),t==="content"&&e.each(this.tooltips,function(e,t){r._updateContent(t)})},_disable:function(){var t=this;e.each(this.tooltips,function(n,r){var i=e.Event("blur");i.target=i.currentTarget=r[0],t.close(i,!0)}),this.element.find(this.options.items).andSelf().each(function(){var t=e(this);t.is("[title]")&&t.data("ui-tooltip-title",t.attr("title")).attr("title","")})},_enable:function(){this.element.find(this.options.items).andSelf().each(function(){var t=e(this);t.data("ui-tooltip-title")&&t.attr("title",t.data("ui-tooltip-title"))})},open:function(t){var n=this,r=e(t?t.target:this.element).closest(this.options.items);if(!r.length||r.data("ui-tooltip-id"))return;r.attr("title")&&r.data("ui-tooltip-title",r.attr("title")),r.data("ui-tooltip-open",!0),t&&t.type==="mouseover"&&r.parents().each(function(){var t=e(this),r;t.data("ui-tooltip-open")&&(r=e.Event("blur"),r.target=r.currentTarget=this,n.close(r,!0)),t.attr("title")&&(t.uniqueId(),n.parents[this.id]={element:this,title:t.attr("title")},t.attr("title",""))}),this._updateContent(r,t)},_updateContent:function(e,t){var n,r=this.options.content,i=this,s=t?t.type:null;if(typeof r=="string")return this._open(t,e,r);n=r.call(e[0],function(n){if(!e.data("ui-tooltip-open"))return;i._delay(function(){t&&(t.type=s),this._open(t,e,n)})}),n&&this._open(t,e,n)},_open:function(t,r,i){function f(e){a.of=e;if(s.is(":hidden"))return;s.position(a)}var s,o,u,a=e.extend({},this.options.position);if(!i)return;s=this._find(r);if(s.length){s.find(".ui-tooltip-content").html(i);return}r.is("[title]")&&(t&&t.type==="mouseover"?r.attr("title",""):r.removeAttr("title")),s=this._tooltip(r),n(r,s.attr("id")),s.find(".ui-tooltip-content").html(i),this.options.track&&t&&/^mouse/.test(t.type)?(this._on(this.document,{mousemove:f}),f(t)):s.position(e.extend({of:r},this.options.position)),s.hide(),this._show(s,this.options.show),this.options.show&&this.options.show.delay&&(u=setInterval(function(){s.is(":visible")&&(f(a.of),clearInterval(u))},e.fx.interval)),this._trigger("open",t,{tooltip:s}),o={keyup:function(t){if(t.keyCode===e.ui.keyCode.ESCAPE){var n=e.Event(t);n.currentTarget=r[0],this.close(n,!0)}},remove:function(){this._removeTooltip(s)}};if(!t||t.type==="mouseover")o.mouseleave="close";if(!t||t.type==="focusin")o.focusout="close";this._on(!0,r,o)},close:function(t){var n=this,i=e(t?t.currentTarget:this.element),s=this._find(i);if(this.closing)return;i.data("ui-tooltip-title")&&i.attr("title",i.data("ui-tooltip-title")),r(i),s.stop(!0),this._hide(s,this.options.hide,function(){n._removeTooltip(e(this))}),i.removeData("ui-tooltip-open"),this._off(i,"mouseleave focusout keyup"),i[0]!==this.element[0]&&this._off(i,"remove"),this._off(this.document,"mousemove"),t&&t.type==="mouseleave"&&e.each(this.parents,function(t,r){e(r.element).attr("title",r.title),delete n.parents[t]}),this.closing=!0,this._trigger("close",t,{tooltip:s}),this.closing=!1},_tooltip:function(n){var r="ui-tooltip-"+t++,i=e("<div>").attr({id:r,role:"tooltip"}).addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||""));return e("<div>").addClass("ui-tooltip-content").appendTo(i),i.appendTo(this.document[0].body),e.fn.bgiframe&&i.bgiframe(),this.tooltips[r]=n,i},_find:function(t){var n=t.data("ui-tooltip-id");return n?e("#"+n):e()},_removeTooltip:function(e){e.remove(),delete this.tooltips[e.attr("id")]},_destroy:function(){var t=this;e.each(this.tooltips,function(n,r){var i=e.Event("blur");i.target=i.currentTarget=r[0],t.close(i,!0),e("#"+n).remove(),r.data("ui-tooltip-title")&&(r.attr("title",r.data("ui-tooltip-title")),r.removeData("ui-tooltip-title"))})}})})(jQuery);
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.cookie.1.0.0.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.cookie.1.0.0.js new file mode 100644 index 000000000..61d3bcef2 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.cookie.1.0.0.js @@ -0,0 +1,91 @@ +/*jslint browser: true */ /*global jQuery: true */ + +/** + * jQuery Cookie plugin + * + * Copyright (c) 2010 Klaus Hartl (stilbuero.de) + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + */ + +// TODO JsDoc + +/** + * Create a cookie with the given key and value and other optional parameters. + * + * @example $.cookie('the_cookie', 'the_value'); + * @desc Set the value of a cookie. + * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true }); + * @desc Create a cookie with all available options. + * @example $.cookie('the_cookie', 'the_value'); + * @desc Create a session cookie. + * @example $.cookie('the_cookie', null); + * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain + * used when the cookie was set. + * + * @param String key The key of the cookie. + * @param String value The value of the cookie. + * @param Object options An object literal containing key/value pairs to provide optional cookie attributes. + * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object. + * If a negative value is specified (e.g. a date in the past), the cookie will be deleted. + * If set to null or omitted, the cookie will be a session cookie and will not be retained + * when the the browser exits. + * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie). + * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie). + * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will + * require a secure protocol (like HTTPS). + * @type undefined + * + * @name $.cookie + * @cat Plugins/Cookie + * @author Klaus Hartl/klaus.hartl@stilbuero.de + */ + +/** + * Get the value of a cookie with the given key. + * + * @example $.cookie('the_cookie'); + * @desc Get the value of a cookie. + * + * @param String key The key of the cookie. + * @return The value of the cookie. + * @type String + * + * @name $.cookie + * @cat Plugins/Cookie + * @author Klaus Hartl/klaus.hartl@stilbuero.de + */ +jQuery.cookie = function (key, value, options) { + + // key and at least value given, set cookie... + if (arguments.length > 1 && String(value) !== "[object Object]") { + options = jQuery.extend({}, options); + + if (value === null || value === undefined) { + options.expires = -1; + } + + if (typeof options.expires === 'number') { + var days = options.expires, t = options.expires = new Date(); + t.setDate(t.getDate() + days); + } + + value = String(value); + + return (document.cookie = [ + encodeURIComponent(key), '=', + options.raw ? value : encodeURIComponent(value), + options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE + options.path ? '; path=' + options.path : '', + options.domain ? '; domain=' + options.domain : '', + options.secure ? '; secure' : '' + ].join('')); + } + + // key and possibly options given, get cookie... + options = value || {}; + var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent; + return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null; +}; diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.fileupload-5.10.0.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.fileupload-5.10.0.js new file mode 100644 index 000000000..8fb856265 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.fileupload-5.10.0.js @@ -0,0 +1,905 @@ +/* + * jQuery File Upload Plugin 5.10.0 + * https://github.com/blueimp/jQuery-File-Upload + * + * Copyright 2010, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/MIT + */ + +/*jslint nomen: true, unparam: true, regexp: true */ +/*global define, window, document, Blob, FormData, location */ + +(function (factory) { + 'use strict'; + if (typeof define === 'function' && define.amd) { + // Register as an anonymous AMD module: + define([ + 'jquery', + 'jquery.ui.widget' + ], factory); + } else { + // Browser globals: + factory(window.jQuery); + } +}(function ($) { + 'use strict'; + + // The FileReader API is not actually used, but works as feature detection, + // as e.g. Safari supports XHR file uploads via the FormData API, + // but not non-multipart XHR file uploads: + $.support.xhrFileUpload = !!(window.XMLHttpRequestUpload && window.FileReader); + $.support.xhrFormDataFileUpload = !!window.FormData; + + // The fileupload widget listens for change events on file input fields defined + // via fileInput setting and paste or drop events of the given dropZone. + // In addition to the default jQuery Widget methods, the fileupload widget + // exposes the "add" and "send" methods, to add or directly send files using + // the fileupload API. + // By default, files added via file input selection, paste, drag & drop or + // "add" method are uploaded immediately, but it is possible to override + // the "add" callback option to queue file uploads. + $.widget('blueimp.fileupload', { + + options: { + // The namespace used for event handler binding on the dropZone and + // fileInput collections. + // If not set, the name of the widget ("fileupload") is used. + namespace: undefined, + // The drop target collection, by the default the complete document. + // Set to null or an empty collection to disable drag & drop support: + dropZone: $(document), + // The file input field collection, that is listened for change events. + // If undefined, it is set to the file input fields inside + // of the widget element on plugin initialization. + // Set to null or an empty collection to disable the change listener. + fileInput: undefined, + // By default, the file input field is replaced with a clone after + // each input field change event. This is required for iframe transport + // queues and allows change events to be fired for the same file + // selection, but can be disabled by setting the following option to false: + replaceFileInput: true, + // The parameter name for the file form data (the request argument name). + // If undefined or empty, the name property of the file input field is + // used, or "files[]" if the file input name property is also empty, + // can be a string or an array of strings: + paramName: undefined, + // By default, each file of a selection is uploaded using an individual + // request for XHR type uploads. Set to false to upload file + // selections in one request each: + singleFileUploads: true, + // To limit the number of files uploaded with one XHR request, + // set the following option to an integer greater than 0: + limitMultiFileUploads: undefined, + // Set the following option to true to issue all file upload requests + // in a sequential order: + sequentialUploads: false, + // To limit the number of concurrent uploads, + // set the following option to an integer greater than 0: + limitConcurrentUploads: undefined, + // Set the following option to true to force iframe transport uploads: + forceIframeTransport: false, + // Set the following option to the location of a redirect url on the + // origin server, for cross-domain iframe transport uploads: + redirect: undefined, + // The parameter name for the redirect url, sent as part of the form + // data and set to 'redirect' if this option is empty: + redirectParamName: undefined, + // Set the following option to the location of a postMessage window, + // to enable postMessage transport uploads: + postMessage: undefined, + // By default, XHR file uploads are sent as multipart/form-data. + // The iframe transport is always using multipart/form-data. + // Set to false to enable non-multipart XHR uploads: + multipart: true, + // To upload large files in smaller chunks, set the following option + // to a preferred maximum chunk size. If set to 0, null or undefined, + // or the browser does not support the required Blob API, files will + // be uploaded as a whole. + maxChunkSize: undefined, + // When a non-multipart upload or a chunked multipart upload has been + // aborted, this option can be used to resume the upload by setting + // it to the size of the already uploaded bytes. This option is most + // useful when modifying the options object inside of the "add" or + // "send" callbacks, as the options are cloned for each file upload. + uploadedBytes: undefined, + // By default, failed (abort or error) file uploads are removed from the + // global progress calculation. Set the following option to false to + // prevent recalculating the global progress data: + recalculateProgress: true, + + // Additional form data to be sent along with the file uploads can be set + // using this option, which accepts an array of objects with name and + // value properties, a function returning such an array, a FormData + // object (for XHR file uploads), or a simple object. + // The form of the first fileInput is given as parameter to the function: + formData: function (form) { + return form.serializeArray(); + }, + + // The add callback is invoked as soon as files are added to the fileupload + // widget (via file input selection, drag & drop, paste or add API call). + // If the singleFileUploads option is enabled, this callback will be + // called once for each file in the selection for XHR file uplaods, else + // once for each file selection. + // The upload starts when the submit method is invoked on the data parameter. + // The data object contains a files property holding the added files + // and allows to override plugin options as well as define ajax settings. + // Listeners for this callback can also be bound the following way: + // .bind('fileuploadadd', func); + // data.submit() returns a Promise object and allows to attach additional + // handlers using jQuery's Deferred callbacks: + // data.submit().done(func).fail(func).always(func); + add: function (e, data) { + data.submit(); + }, + + // Other callbacks: + // Callback for the submit event of each file upload: + // submit: function (e, data) {}, // .bind('fileuploadsubmit', func); + // Callback for the start of each file upload request: + // send: function (e, data) {}, // .bind('fileuploadsend', func); + // Callback for successful uploads: + // done: function (e, data) {}, // .bind('fileuploaddone', func); + // Callback for failed (abort or error) uploads: + // fail: function (e, data) {}, // .bind('fileuploadfail', func); + // Callback for completed (success, abort or error) requests: + // always: function (e, data) {}, // .bind('fileuploadalways', func); + // Callback for upload progress events: + // progress: function (e, data) {}, // .bind('fileuploadprogress', func); + // Callback for global upload progress events: + // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func); + // Callback for uploads start, equivalent to the global ajaxStart event: + // start: function (e) {}, // .bind('fileuploadstart', func); + // Callback for uploads stop, equivalent to the global ajaxStop event: + // stop: function (e) {}, // .bind('fileuploadstop', func); + // Callback for change events of the fileInput collection: + // change: function (e, data) {}, // .bind('fileuploadchange', func); + // Callback for paste events to the dropZone collection: + // paste: function (e, data) {}, // .bind('fileuploadpaste', func); + // Callback for drop events of the dropZone collection: + // drop: function (e, data) {}, // .bind('fileuploaddrop', func); + // Callback for dragover events of the dropZone collection: + // dragover: function (e) {}, // .bind('fileuploaddragover', func); + + // The plugin options are used as settings object for the ajax calls. + // The following are jQuery ajax settings required for the file uploads: + processData: false, + contentType: false, + cache: false + }, + + // A list of options that require a refresh after assigning a new value: + _refreshOptionsList: [ + 'namespace', + 'dropZone', + 'fileInput', + 'multipart', + 'forceIframeTransport' + ], + + _isXHRUpload: function (options) { + return !options.forceIframeTransport && + ((!options.multipart && $.support.xhrFileUpload) || + $.support.xhrFormDataFileUpload); + }, + + _getFormData: function (options) { + var formData; + if (typeof options.formData === 'function') { + return options.formData(options.form); + } else if ($.isArray(options.formData)) { + return options.formData; + } else if (options.formData) { + formData = []; + $.each(options.formData, function (name, value) { + formData.push({name: name, value: value}); + }); + return formData; + } + return []; + }, + + _getTotal: function (files) { + var total = 0; + $.each(files, function (index, file) { + total += file.size || 1; + }); + return total; + }, + + _onProgress: function (e, data) { + if (e.lengthComputable) { + var total = data.total || this._getTotal(data.files), + loaded = parseInt( + e.loaded / e.total * (data.chunkSize || total), + 10 + ) + (data.uploadedBytes || 0); + this._loaded += loaded - (data.loaded || data.uploadedBytes || 0); + data.lengthComputable = true; + data.loaded = loaded; + data.total = total; + // Trigger a custom progress event with a total data property set + // to the file size(s) of the current upload and a loaded data + // property calculated accordingly: + this._trigger('progress', e, data); + // Trigger a global progress event for all current file uploads, + // including ajax calls queued for sequential file uploads: + this._trigger('progressall', e, { + lengthComputable: true, + loaded: this._loaded, + total: this._total + }); + } + }, + + _initProgressListener: function (options) { + var that = this, + xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr(); + // Accesss to the native XHR object is required to add event listeners + // for the upload progress event: + if (xhr.upload) { + $(xhr.upload).bind('progress', function (e) { + var oe = e.originalEvent; + // Make sure the progress event properties get copied over: + e.lengthComputable = oe.lengthComputable; + e.loaded = oe.loaded; + e.total = oe.total; + that._onProgress(e, options); + }); + options.xhr = function () { + return xhr; + }; + } + }, + + _initXHRData: function (options) { + var formData, + file = options.files[0], + // Ignore non-multipart setting if not supported: + multipart = options.multipart || !$.support.xhrFileUpload, + paramName = options.paramName[0]; + if (!multipart || options.blob) { + // For non-multipart uploads and chunked uploads, + // file meta data is not part of the request body, + // so we transmit this data as part of the HTTP headers. + // For cross domain requests, these headers must be allowed + // via Access-Control-Allow-Headers or removed using + // the beforeSend callback: + options.headers = $.extend(options.headers, { + 'X-File-Name': file.name, + 'X-File-Type': file.type, + 'X-File-Size': file.size + }); + if (!options.blob) { + // Non-chunked non-multipart upload: + options.contentType = file.type; + options.data = file; + } else if (!multipart) { + // Chunked non-multipart upload: + options.contentType = 'application/octet-stream'; + options.data = options.blob; + } + } + if (multipart && $.support.xhrFormDataFileUpload) { + if (options.postMessage) { + // window.postMessage does not allow sending FormData + // objects, so we just add the File/Blob objects to + // the formData array and let the postMessage window + // create the FormData object out of this array: + formData = this._getFormData(options); + if (options.blob) { + formData.push({ + name: paramName, + value: options.blob + }); + } else { + $.each(options.files, function (index, file) { + formData.push({ + name: options.paramName[index] || paramName, + value: file + }); + }); + } + } else { + if (options.formData instanceof FormData) { + formData = options.formData; + } else { + formData = new FormData(); + $.each(this._getFormData(options), function (index, field) { + formData.append(field.name, field.value); + }); + } + if (options.blob) { + formData.append(paramName, options.blob, file.name); + } else { + $.each(options.files, function (index, file) { + // File objects are also Blob instances. + // This check allows the tests to run with + // dummy objects: + if (file instanceof Blob) { + formData.append( + options.paramName[index] || paramName, + file, + file.name + ); + } + }); + } + } + options.data = formData; + } + // Blob reference is not needed anymore, free memory: + options.blob = null; + }, + + _initIframeSettings: function (options) { + // Setting the dataType to iframe enables the iframe transport: + options.dataType = 'iframe ' + (options.dataType || ''); + // The iframe transport accepts a serialized array as form data: + options.formData = this._getFormData(options); + // Add redirect url to form data on cross-domain uploads: + if (options.redirect && $('<a></a>').prop('href', options.url) + .prop('host') !== location.host) { + options.formData.push({ + name: options.redirectParamName || 'redirect', + value: options.redirect + }); + } + }, + + _initDataSettings: function (options) { + if (this._isXHRUpload(options)) { + if (!this._chunkedUpload(options, true)) { + if (!options.data) { + this._initXHRData(options); + } + this._initProgressListener(options); + } + if (options.postMessage) { + // Setting the dataType to postmessage enables the + // postMessage transport: + options.dataType = 'postmessage ' + (options.dataType || ''); + } + } else { + this._initIframeSettings(options, 'iframe'); + } + }, + + _getParamName: function (options) { + var fileInput = $(options.fileInput), + paramName = options.paramName; + if (!paramName) { + paramName = []; + fileInput.each(function () { + var input = $(this), + name = input.prop('name') || 'files[]', + i = (input.prop('files') || [1]).length; + while (i) { + paramName.push(name); + i -= 1; + } + }); + if (!paramName.length) { + paramName = [fileInput.prop('name') || 'files[]']; + } + } else if (!$.isArray(paramName)) { + paramName = [paramName]; + } + return paramName; + }, + + _initFormSettings: function (options) { + // Retrieve missing options from the input field and the + // associated form, if available: + if (!options.form || !options.form.length) { + options.form = $(options.fileInput.prop('form')); + } + options.paramName = this._getParamName(options); + if (!options.url) { + options.url = options.form.prop('action') || location.href; + } + // The HTTP request method must be "POST" or "PUT": + options.type = (options.type || options.form.prop('method') || '') + .toUpperCase(); + if (options.type !== 'POST' && options.type !== 'PUT') { + options.type = 'POST'; + } + }, + + _getAJAXSettings: function (data) { + var options = $.extend({}, this.options, data); + this._initFormSettings(options); + this._initDataSettings(options); + return options; + }, + + // Maps jqXHR callbacks to the equivalent + // methods of the given Promise object: + _enhancePromise: function (promise) { + promise.success = promise.done; + promise.error = promise.fail; + promise.complete = promise.always; + return promise; + }, + + // Creates and returns a Promise object enhanced with + // the jqXHR methods abort, success, error and complete: + _getXHRPromise: function (resolveOrReject, context, args) { + var dfd = $.Deferred(), + promise = dfd.promise(); + context = context || this.options.context || promise; + if (resolveOrReject === true) { + dfd.resolveWith(context, args); + } else if (resolveOrReject === false) { + dfd.rejectWith(context, args); + } + promise.abort = dfd.promise; + return this._enhancePromise(promise); + }, + + // Uploads a file in multiple, sequential requests + // by splitting the file up in multiple blob chunks. + // If the second parameter is true, only tests if the file + // should be uploaded in chunks, but does not invoke any + // upload requests: + _chunkedUpload: function (options, testOnly) { + var that = this, + file = options.files[0], + fs = file.size, + ub = options.uploadedBytes = options.uploadedBytes || 0, + mcs = options.maxChunkSize || fs, + // Use the Blob methods with the slice implementation + // according to the W3C Blob API specification: + slice = file.webkitSlice || file.mozSlice || file.slice, + upload, + n, + jqXHR, + pipe; + if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) || + options.data) { + return false; + } + if (testOnly) { + return true; + } + if (ub >= fs) { + file.error = 'uploadedBytes'; + return this._getXHRPromise( + false, + options.context, + [null, 'error', file.error] + ); + } + // n is the number of blobs to upload, + // calculated via filesize, uploaded bytes and max chunk size: + n = Math.ceil((fs - ub) / mcs); + // The chunk upload method accepting the chunk number as parameter: + upload = function (i) { + if (!i) { + return that._getXHRPromise(true, options.context); + } + // Upload the blobs in sequential order: + return upload(i -= 1).pipe(function () { + // Clone the options object for each chunk upload: + var o = $.extend({}, options); + o.blob = slice.call( + file, + ub + i * mcs, + ub + (i + 1) * mcs + ); + // Store the current chunk size, as the blob itself + // will be dereferenced after data processing: + o.chunkSize = o.blob.size; + // Process the upload data (the blob and potential form data): + that._initXHRData(o); + // Add progress listeners for this chunk upload: + that._initProgressListener(o); + jqXHR = ($.ajax(o) || that._getXHRPromise(false, o.context)) + .done(function () { + // Create a progress event if upload is done and + // no progress event has been invoked for this chunk: + if (!o.loaded) { + that._onProgress($.Event('progress', { + lengthComputable: true, + loaded: o.chunkSize, + total: o.chunkSize + }), o); + } + options.uploadedBytes = o.uploadedBytes += + o.chunkSize; + }); + return jqXHR; + }); + }; + // Return the piped Promise object, enhanced with an abort method, + // which is delegated to the jqXHR object of the current upload, + // and jqXHR callbacks mapped to the equivalent Promise methods: + pipe = upload(n); + pipe.abort = function () { + return jqXHR.abort(); + }; + return this._enhancePromise(pipe); + }, + + _beforeSend: function (e, data) { + if (this._active === 0) { + // the start callback is triggered when an upload starts + // and no other uploads are currently running, + // equivalent to the global ajaxStart event: + this._trigger('start'); + } + this._active += 1; + // Initialize the global progress values: + this._loaded += data.uploadedBytes || 0; + this._total += this._getTotal(data.files); + }, + + _onDone: function (result, textStatus, jqXHR, options) { + if (!this._isXHRUpload(options)) { + // Create a progress event for each iframe load: + this._onProgress($.Event('progress', { + lengthComputable: true, + loaded: 1, + total: 1 + }), options); + } + options.result = result; + options.textStatus = textStatus; + options.jqXHR = jqXHR; + this._trigger('done', null, options); + }, + + _onFail: function (jqXHR, textStatus, errorThrown, options) { + options.jqXHR = jqXHR; + options.textStatus = textStatus; + options.errorThrown = errorThrown; + this._trigger('fail', null, options); + if (options.recalculateProgress) { + // Remove the failed (error or abort) file upload from + // the global progress calculation: + this._loaded -= options.loaded || options.uploadedBytes || 0; + this._total -= options.total || this._getTotal(options.files); + } + }, + + _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) { + this._active -= 1; + options.textStatus = textStatus; + if (jqXHRorError && jqXHRorError.always) { + options.jqXHR = jqXHRorError; + options.result = jqXHRorResult; + } else { + options.jqXHR = jqXHRorResult; + options.errorThrown = jqXHRorError; + } + this._trigger('always', null, options); + if (this._active === 0) { + // The stop callback is triggered when all uploads have + // been completed, equivalent to the global ajaxStop event: + this._trigger('stop'); + // Reset the global progress values: + this._loaded = this._total = 0; + } + }, + + _onSend: function (e, data) { + var that = this, + jqXHR, + slot, + pipe, + options = that._getAJAXSettings(data), + send = function (resolve, args) { + that._sending += 1; + jqXHR = jqXHR || ( + (resolve !== false && + that._trigger('send', e, options) !== false && + (that._chunkedUpload(options) || $.ajax(options))) || + that._getXHRPromise(false, options.context, args) + ).done(function (result, textStatus, jqXHR) { + that._onDone(result, textStatus, jqXHR, options); + }).fail(function (jqXHR, textStatus, errorThrown) { + that._onFail(jqXHR, textStatus, errorThrown, options); + }).always(function (jqXHRorResult, textStatus, jqXHRorError) { + that._sending -= 1; + that._onAlways( + jqXHRorResult, + textStatus, + jqXHRorError, + options + ); + if (options.limitConcurrentUploads && + options.limitConcurrentUploads > that._sending) { + // Start the next queued upload, + // that has not been aborted: + var nextSlot = that._slots.shift(); + while (nextSlot) { + if (!nextSlot.isRejected()) { + nextSlot.resolve(); + break; + } + nextSlot = that._slots.shift(); + } + } + }); + return jqXHR; + }; + this._beforeSend(e, options); + if (this.options.sequentialUploads || + (this.options.limitConcurrentUploads && + this.options.limitConcurrentUploads <= this._sending)) { + if (this.options.limitConcurrentUploads > 1) { + slot = $.Deferred(); + this._slots.push(slot); + pipe = slot.pipe(send); + } else { + pipe = (this._sequence = this._sequence.pipe(send, send)); + } + // Return the piped Promise object, enhanced with an abort method, + // which is delegated to the jqXHR object of the current upload, + // and jqXHR callbacks mapped to the equivalent Promise methods: + pipe.abort = function () { + var args = [undefined, 'abort', 'abort']; + if (!jqXHR) { + if (slot) { + slot.rejectWith(args); + } + return send(false, args); + } + return jqXHR.abort(); + }; + return this._enhancePromise(pipe); + } + return send(); + }, + + _onAdd: function (e, data) { + var that = this, + result = true, + options = $.extend({}, this.options, data), + limit = options.limitMultiFileUploads, + paramName = this._getParamName(options), + paramNameSet, + paramNameSlice, + fileSet, + i; + if (!(options.singleFileUploads || limit) || + !this._isXHRUpload(options)) { + fileSet = [data.files]; + paramNameSet = [paramName]; + } else if (!options.singleFileUploads && limit) { + fileSet = []; + paramNameSet = []; + for (i = 0; i < data.files.length; i += limit) { + fileSet.push(data.files.slice(i, i + limit)); + paramNameSlice = paramName.slice(i, i + limit); + if (!paramNameSlice.length) { + paramNameSlice = paramName; + } + paramNameSet.push(paramNameSlice); + } + } else { + paramNameSet = paramName; + } + data.originalFiles = data.files; + $.each(fileSet || data.files, function (index, element) { + var newData = $.extend({}, data); + newData.files = fileSet ? element : [element]; + newData.paramName = paramNameSet[index]; + newData.submit = function () { + newData.jqXHR = this.jqXHR = + (that._trigger('submit', e, this) !== false) && + that._onSend(e, this); + return this.jqXHR; + }; + return (result = that._trigger('add', e, newData)); + }); + return result; + }, + + // File Normalization for Gecko 1.9.1 (Firefox 3.5) support: + _normalizeFile: function (index, file) { + if (file.name === undefined && file.size === undefined) { + file.name = file.fileName; + file.size = file.fileSize; + } + }, + + _replaceFileInput: function (input) { + var inputClone = input.clone(true); + $('<form></form>').append(inputClone)[0].reset(); + // Detaching allows to insert the fileInput on another form + // without loosing the file input value: + input.after(inputClone).detach(); + // Avoid memory leaks with the detached file input: + $.cleanData(input.unbind('remove')); + // Replace the original file input element in the fileInput + // collection with the clone, which has been copied including + // event handlers: + this.options.fileInput = this.options.fileInput.map(function (i, el) { + if (el === input[0]) { + return inputClone[0]; + } + return el; + }); + // If the widget has been initialized on the file input itself, + // override this.element with the file input clone: + if (input[0] === this.element[0]) { + this.element = inputClone; + } + }, + + _onChange: function (e) { + var that = e.data.fileupload, + data = { + files: $.each($.makeArray(e.target.files), that._normalizeFile), + fileInput: $(e.target), + form: $(e.target.form) + }; + if (!data.files.length) { + // If the files property is not available, the browser does not + // support the File API and we add a pseudo File object with + // the input value as name with path information removed: + data.files = [{name: e.target.value.replace(/^.*\\/, '')}]; + } + if (that.options.replaceFileInput) { + that._replaceFileInput(data.fileInput); + } + if (that._trigger('change', e, data) === false || + that._onAdd(e, data) === false) { + return false; + } + }, + + _onPaste: function (e) { + var that = e.data.fileupload, + cbd = e.originalEvent.clipboardData, + items = (cbd && cbd.items) || [], + data = {files: []}; + $.each(items, function (index, item) { + var file = item.getAsFile && item.getAsFile(); + if (file) { + data.files.push(file); + } + }); + if (that._trigger('paste', e, data) === false || + that._onAdd(e, data) === false) { + return false; + } + }, + + _onDrop: function (e) { + var that = e.data.fileupload, + dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer, + data = { + files: $.each( + $.makeArray(dataTransfer && dataTransfer.files), + that._normalizeFile + ) + }; + if (that._trigger('drop', e, data) === false || + that._onAdd(e, data) === false) { + return false; + } + e.preventDefault(); + }, + + _onDragOver: function (e) { + var that = e.data.fileupload, + dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer; + if (that._trigger('dragover', e) === false) { + return false; + } + if (dataTransfer) { + dataTransfer.dropEffect = dataTransfer.effectAllowed = 'copy'; + } + e.preventDefault(); + }, + + _initEventHandlers: function () { + var ns = this.options.namespace; + if (this._isXHRUpload(this.options)) { + this.options.dropZone + .bind('dragover.' + ns, {fileupload: this}, this._onDragOver) + .bind('drop.' + ns, {fileupload: this}, this._onDrop) + .bind('paste.' + ns, {fileupload: this}, this._onPaste); + } + this.options.fileInput + .bind('change.' + ns, {fileupload: this}, this._onChange); + }, + + _destroyEventHandlers: function () { + var ns = this.options.namespace; + this.options.dropZone + .unbind('dragover.' + ns, this._onDragOver) + .unbind('drop.' + ns, this._onDrop) + .unbind('paste.' + ns, this._onPaste); + this.options.fileInput + .unbind('change.' + ns, this._onChange); + }, + + _setOption: function (key, value) { + var refresh = $.inArray(key, this._refreshOptionsList) !== -1; + if (refresh) { + this._destroyEventHandlers(); + } + $.Widget.prototype._setOption.call(this, key, value); + if (refresh) { + this._initSpecialOptions(); + this._initEventHandlers(); + } + }, + + _initSpecialOptions: function () { + var options = this.options; + if (options.fileInput === undefined) { + options.fileInput = this.element.is('input:file') ? + this.element : this.element.find('input:file'); + } else if (!(options.fileInput instanceof $)) { + options.fileInput = $(options.fileInput); + } + if (!(options.dropZone instanceof $)) { + options.dropZone = $(options.dropZone); + } + }, + + _create: function () { + var options = this.options, + dataOpts = $.extend({}, this.element.data()); + dataOpts[this.widgetName] = undefined; + $.extend(options, dataOpts); + options.namespace = options.namespace || this.widgetName; + this._initSpecialOptions(); + this._slots = []; + this._sequence = this._getXHRPromise(true); + this._sending = this._active = this._loaded = this._total = 0; + this._initEventHandlers(); + }, + + destroy: function () { + this._destroyEventHandlers(); + $.Widget.prototype.destroy.call(this); + }, + + enable: function () { + $.Widget.prototype.enable.call(this); + this._initEventHandlers(); + }, + + disable: function () { + this._destroyEventHandlers(); + $.Widget.prototype.disable.call(this); + }, + + // This method is exposed to the widget API and allows adding files + // using the fileupload API. The data parameter accepts an object which + // must have a files property and can contain additional options: + // .fileupload('add', {files: filesList}); + add: function (data) { + if (!data || this.options.disabled) { + return; + } + data.files = $.each($.makeArray(data.files), this._normalizeFile); + this._onAdd(null, data); + }, + + // This method is exposed to the widget API and allows sending files + // using the fileupload API. The data parameter accepts an object which + // must have a files property and can contain additional options: + // .fileupload('send', {files: filesList}); + // The method returns a Promise object for the file upload call. + send: function (data) { + if (data && !this.options.disabled) { + data.files = $.each($.makeArray(data.files), this._normalizeFile); + if (data.files.length) { + return this._onSend(null, data); + } + } + return this._getXHRPromise(false, data && data.context); + } + + }); + +})); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.fileupload-ip-1.0.6.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.fileupload-ip-1.0.6.js new file mode 100644 index 000000000..7b998032f --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.fileupload-ip-1.0.6.js @@ -0,0 +1,160 @@ +/* + * jQuery File Upload Image Processing Plugin 1.0.6 + * https://github.com/blueimp/jQuery-File-Upload + * + * Copyright 2012, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/MIT + */ + +/*jslint nomen: true, unparam: true, regexp: true */ +/*global define, window, document */ + +(function (factory) { + 'use strict'; + if (typeof define === 'function' && define.amd) { + // Register as an anonymous AMD module: + define([ + 'jquery', + //'load-image', + //'canvas-to-blob', + 'jquery.fileupload' + ], factory); + } else { + // Browser globals: + factory( + window.jQuery, + window.loadImage, + window.canvasToBlob + ); + } +}(function ($, loadImage, canvasToBlob) { + 'use strict'; + + // The File Upload IP version extends the basic fileupload widget + // with image processing functionality: + $.widget('blueimpIP.fileupload', $.blueimp.fileupload, { + + options: { + // The regular expression to define which image files are to be + // resized, given that the browser supports the operation: + resizeSourceFileTypes: /^image\/(gif|jpeg|png)$/, + // The maximum file size of images that are to be resized: + resizeSourceMaxFileSize: 20000000, // 20MB + // The maximum width of the resized images: + resizeMaxWidth: undefined, + // The maximum height of the resized images: + resizeMaxHeight: undefined, + // The minimum width of the resized images: + resizeMinWidth: undefined, + // The minimum height of the resized images: + resizeMinHeight: undefined, + + // The add callback is invoked as soon as files are added to the fileupload + // widget (via file input selection, drag & drop or add API call). + // See the basic file upload widget for more information: + add: function (e, data) { + $(this).fileupload('resize', data).done(function () { + data.submit(); + }); + } + }, + + // Resizes the image file at the given index and stores the created blob + // at the original position of the files list, returns a Promise object: + _resizeImage: function (files, index, options) { + var that = this, + file = files[index], + deferred = $.Deferred(), + canvas, + blob; + options = options || this.options; + loadImage( + file, + function (img) { + var width = img.width, + height = img.height; + canvas = loadImage.scale(img, { + maxWidth: options.resizeMaxWidth, + maxHeight: options.resizeMaxHeight, + minWidth: options.resizeMinWidth, + minHeight: options.resizeMinHeight, + canvas: true + }); + if (width !== canvas.width || height !== canvas.height) { + canvasToBlob(canvas, function (blob) { + if (!blob.name) { + if (file.type === blob.type) { + blob.name = file.name; + } else if (file.name) { + blob.name = file.name.replace( + /\..+$/, + '.' + blob.type.substr(6) + ); + } + } + files[index] = blob; + deferred.resolveWith(that); + }, file); + } else { + deferred.resolveWith(that); + } + } + ); + return deferred.promise(); + }, + + // Resizes the images given as files property of the data parameter, + // returns a Promise object that allows to bind a done handler, which + // will be invoked after processing all images is done: + resize: function (data) { + var that = this, + options = $.extend({}, this.options, data), + resizeAll = $.type(options.resizeSourceMaxFileSize) !== 'number', + isXHRUpload = this._isXHRUpload(options); + $.each(data.files, function (index, file) { + if (isXHRUpload && that._resizeSupport && + (options.resizeMaxWidth || options.resizeMaxHeight || + options.resizeMinWidth || options.resizeMinHeight) && + (resizeAll || file.size < options.resizeSourceMaxFileSize) && + options.resizeSourceFileTypes.test(file.type)) { + that._processing += 1; + if (that._processing === 1) { + that.element.addClass('fileupload-processing'); + } + that._processingQueue = that._processingQueue.pipe(function () { + var deferred = $.Deferred(); + that._resizeImage( + data.files, + index, + options + ).done(function () { + that._processing -= 1; + if (that._processing === 0) { + that.element + .removeClass('fileupload-processing'); + } + deferred.resolveWith(that); + }); + return deferred.promise(); + }); + } + }); + return this._processingQueue; + }, + + _create: function () { + $.blueimp.fileupload.prototype._create.call(this); + this._processing = 0; + this._processingQueue = $.Deferred().resolveWith(this).promise(); + this._resizeSupport = canvasToBlob && canvasToBlob( + document.createElement('canvas'), + $.noop + ); + } + + }); + +})); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.fileupload-ui-6.6.3.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.fileupload-ui-6.6.3.js new file mode 100644 index 000000000..c2c48a8aa --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.fileupload-ui-6.6.3.js @@ -0,0 +1,630 @@ +/* + * jQuery File Upload User Interface Plugin 6.6.3 + * https://github.com/blueimp/jQuery-File-Upload + * + * Copyright 2010, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/MIT + */ + +/*jslint nomen: true, unparam: true, regexp: true */ +/*global define, window, document, URL, webkitURL, FileReader */ + +(function (factory) { + 'use strict'; + if (typeof define === 'function' && define.amd) { + // Register as an anonymous AMD module: + define([ + 'jquery', + 'tmpl', + //'load-image', + 'jquery.fileupload.ip' + ], factory); + } else { + // Browser globals: + factory( + window.jQuery, + window.tmpl, + window.loadImage + ); + } +}(function ($, tmpl, loadImage) { + 'use strict'; + + // The UI version extends the IP (image processing) version or the basic + // file upload widget and adds complete user interface interaction: + var parentWidget = ($.blueimpIP || $.blueimp).fileupload; + $.widget('blueimpUI.fileupload', parentWidget, { + + options: { + // By default, files added to the widget are uploaded as soon + // as the user clicks on the start buttons. To enable automatic + // uploads, set the following option to true: + autoUpload: false, + // The following option limits the number of files that are + // allowed to be uploaded using this widget: + maxNumberOfFiles: undefined, + // The maximum allowed file size: + maxFileSize: undefined, + // The minimum allowed file size: + minFileSize: undefined, + // The regular expression for allowed file types, matches + // against either file type or file name: + acceptFileTypes: /.+$/i, + // The regular expression to define for which files a preview + // image is shown, matched against the file type: + previewSourceFileTypes: /^image\/(gif|jpeg|png)$/, + // The maximum file size of images that are to be displayed as preview: + previewSourceMaxFileSize: 5000000, // 5MB + // The maximum width of the preview images: + previewMaxWidth: 80, + // The maximum height of the preview images: + previewMaxHeight: 80, + // By default, preview images are displayed as canvas elements + // if supported by the browser. Set the following option to false + // to always display preview images as img elements: + previewAsCanvas: true, + // The ID of the upload template: + uploadTemplateId: 'template-upload', + // The ID of the download template: + downloadTemplateId: 'template-download', + // The expected data type of the upload response, sets the dataType + // option of the $.ajax upload requests: + dataType: 'json', + + // The add callback is invoked as soon as files are added to the fileupload + // widget (via file input selection, drag & drop or add API call). + // See the basic file upload widget for more information: + add: function (e, data) { + var that = $(this).data('fileupload'), + options = that.options, + files = data.files; + $(this).fileupload('resize', data).done(data, function () { + that._adjustMaxNumberOfFiles(-files.length); + data.isAdjusted = true; + data.files.valid = data.isValidated = that._validate(files); + data.context = that._renderUpload(files) + .appendTo(options.filesContainer) + .data('data', data); + that._renderPreviews(files, data.context); + that._forceReflow(data.context); + that._transition(data.context).done( + function () { + if ((that._trigger('added', e, data) !== false) && + (options.autoUpload || data.autoUpload) && + data.autoUpload !== false && data.isValidated) { + data.submit(); + } + } + ); + }); + }, + // Callback for the start of each file upload request: + send: function (e, data) { + var that = $(this).data('fileupload'); + if (!data.isValidated) { + if (!data.isAdjusted) { + that._adjustMaxNumberOfFiles(-data.files.length); + } + if (!that._validate(data.files)) { + return false; + } + } + if (data.context && data.dataType && + data.dataType.substr(0, 6) === 'iframe') { + // Iframe Transport does not support progress events. + // In lack of an indeterminate progress bar, we set + // the progress to 100%, showing the full animated bar: + data.context + .find('.progress').addClass( + !$.support.transition && 'progress-animated' + ) + .find('.bar').css( + 'width', + parseInt(100, 10) + '%' + ); + } + return that._trigger('sent', e, data); + }, + // Callback for successful uploads: + done: function (e, data) { + var that = $(this).data('fileupload'), + template, + preview; + if (data.context) { + + data.context.each(function (index, e) { + var file = ($.isArray(data.result) && + data.result[index]) || data.result || {error: 'emptyResult'}; + if (file.error) { + that._adjustMaxNumberOfFiles(1); + } + that._transition($(this)).done( + function () { + var node = $(this); + template = that._renderDownload([file]) + .css('height', node.height()) + .replaceAll(node); + that._forceReflow(template); + that._transition(template).done( + function () { + data.context = $(this); + that._trigger('completed', e, data); + } + ); + } + ); + }); + } else { + template = that._renderDownload(data.result) + .appendTo(that.options.filesContainer); + that._forceReflow(template); + that._transition(template).done( + function () { + data.context = $(this); + that._trigger('completed', e, data); + } + ); + } + }, + // Callback for failed (abort or error) uploads: + fail: function (e, data) { + var that = $(this).data('fileupload'), + template; + that._adjustMaxNumberOfFiles(data.files.length); + if (data.context) { + data.context.each(function (index) { + if (data.errorThrown !== 'abort') { + var file = data.files[index]; + file.error = file.error || data.errorThrown || + true; + that._transition($(this)).done( + function () { + var node = $(this); + template = that._renderDownload([file]) + .replaceAll(node); + that._forceReflow(template); + that._transition(template).done( + function () { + data.context = $(this); + that._trigger('failed', e, data); + } + ); + } + ); + } else { + that._transition($(this)).done( + function () { + $(this).remove(); + that._trigger('failed', e, data); + } + ); + } + }); + } else if (data.errorThrown !== 'abort') { + that._adjustMaxNumberOfFiles(-data.files.length); + data.context = that._renderUpload(data.files) + .appendTo(that.options.filesContainer) + .data('data', data); + that._forceReflow(data.context); + that._transition(data.context).done( + function () { + data.context = $(this); + that._trigger('failed', e, data); + } + ); + } else { + that._trigger('failed', e, data); + } + }, + // Callback for upload progress events: + progress: function (e, data) { + if (data.context) { + data.context.find('.progress .bar').css( + 'width', + parseInt(data.loaded / data.total * 100, 10) + '%' + ); + } + }, + // Callback for global upload progress events: + progressall: function (e, data) { + $(this).find('.fileupload-buttonbar .progress .bar').css( + 'width', + parseInt(data.loaded / data.total * 100, 10) + '%' + ); + }, + // Callback for uploads start, equivalent to the global ajaxStart event: + start: function (e) { + var that = $(this).data('fileupload'); + that._transition($(this).find('.fileupload-buttonbar .progress')).done( + function () { + that._trigger('started', e); + } + ); + }, + // Callback for uploads stop, equivalent to the global ajaxStop event: + stop: function (e) { + var that = $(this).data('fileupload'); + that._transition($(this).find('.fileupload-buttonbar .progress')).done( + function () { + $(this).find('.bar').css('width', '0%'); + that._trigger('stopped', e); + } + ); + }, + // Callback for file deletion: + destroy: function (e, data) { + var that = $(this).data('fileupload'); + if (data.url) { + $.ajax(data); + } + that._adjustMaxNumberOfFiles(1); + that._transition(data.context).done( + function () { + $(this).remove(); + that._trigger('destroyed', e, data); + } + ); + } + }, + + // Link handler, that allows to download files + // by drag & drop of the links to the desktop: + _enableDragToDesktop: function () { + var link = $(this), + url = link.prop('href'), + name = link.prop('download'), + type = 'application/octet-stream'; + link.bind('dragstart', function (e) { + try { + e.originalEvent.dataTransfer.setData( + 'DownloadURL', + [type, name, url].join(':') + ); + } catch (err) {} + }); + }, + + _adjustMaxNumberOfFiles: function (operand) { + if (typeof this.options.maxNumberOfFiles === 'number') { + this.options.maxNumberOfFiles += operand; + if (this.options.maxNumberOfFiles < 1) { + this._disableFileInputButton(); + } else { + this._enableFileInputButton(); + } + } + }, + + _formatFileSize: function (bytes) { + if (typeof bytes !== 'number') { + return ''; + } + if (bytes >= 1000000000) { + return (bytes / 1000000000).toFixed(2) + ' GB'; + } + if (bytes >= 1000000) { + return (bytes / 1000000).toFixed(2) + ' MB'; + } + return (bytes / 1000).toFixed(2) + ' KB'; + }, + + _hasError: function (file) { + if (file.error) { + return file.error; + } + // The number of added files is subtracted from + // maxNumberOfFiles before validation, so we check if + // maxNumberOfFiles is below 0 (instead of below 1): + if (this.options.maxNumberOfFiles < 0) { + return 'maxNumberOfFiles'; + } + // Files are accepted if either the file type or the file name + // matches against the acceptFileTypes regular expression, as + // only browsers with support for the File API report the type: + if (!(this.options.acceptFileTypes.test(file.type) || + this.options.acceptFileTypes.test(file.name))) { + return 'acceptFileTypes'; + } + if (this.options.maxFileSize && + file.size > this.options.maxFileSize) { + return 'maxFileSize'; + } + if (typeof file.size === 'number' && + file.size < this.options.minFileSize) { + return 'minFileSize'; + } + return null; + }, + + _validate: function (files) { + var that = this, + valid = !!files.length; + $.each(files, function (index, file) { + file.error = that._hasError(file); + if (file.error) { + valid = false; + } + }); + return valid; + }, + + _renderTemplate: function (func, files) { + if (!func) { + return $(); + } + var result = func({ + files: files, + formatFileSize: this._formatFileSize, + options: this.options + }); + if (result instanceof $) { + return result; + } + return $(this.options.templatesContainer).html(result).children(); + }, + + _renderPreview: function (file, node) { + var that = this, + options = this.options, + deferred = $.Deferred(); + return ((loadImage && loadImage( + file, + function (img) { + node.append(img); + that._forceReflow(node); + that._transition(node).done(function () { + deferred.resolveWith(node); + }); + }, + { + maxWidth: options.previewMaxWidth, + maxHeight: options.previewMaxHeight, + canvas: options.previewAsCanvas + } + )) || deferred.resolveWith(node)) && deferred; + }, + + _renderPreviews: function (files, nodes) { + var that = this, + options = this.options; + nodes.find('.preview span').each(function (index, element) { + var file = files[index]; + if (options.previewSourceFileTypes.test(file.type) && + ($.type(options.previewSourceMaxFileSize) !== 'number' || + file.size < options.previewSourceMaxFileSize)) { + that._processingQueue = that._processingQueue.pipe(function () { + var deferred = $.Deferred(); + that._renderPreview(file, $(element)).done( + function () { + deferred.resolveWith(that); + } + ); + return deferred.promise(); + }); + } + }); + return this._processingQueue; + }, + + _renderUpload: function (files) { + return this._renderTemplate( + this.options.uploadTemplate, + files + ); + }, + + _renderDownload: function (files) { + return this._renderTemplate( + this.options.downloadTemplate, + files + ).find('a[download]').each(this._enableDragToDesktop).end(); + }, + + _startHandler: function (e) { + e.preventDefault(); + var button = $(this), + template = button.closest('.template-upload'), + data = template.data('data'); + if (data && data.submit && !data.jqXHR && data.submit()) { + button.prop('disabled', true); + } + }, + + _cancelHandler: function (e) { + e.preventDefault(); + var template = $(this).closest('.template-upload'), + data = template.data('data') || {}; + if (!data.jqXHR) { + data.errorThrown = 'abort'; + e.data.fileupload._trigger('fail', e, data); + } else { + data.jqXHR.abort(); + } + }, + + _deleteHandler: function (e) { + e.preventDefault(); + var button = $(this); + e.data.fileupload._trigger('destroy', e, { + context: button.closest('.template-download'), + url: button.attr('data-url'), + type: button.attr('data-type') || 'DELETE', + dataType: e.data.fileupload.options.dataType + }); + }, + + _forceReflow: function (node) { + this._reflow = $.support.transition && + node.length && node[0].offsetWidth; + }, + + _transition: function (node) { + var that = this, + deferred = $.Deferred(); + if ($.support.transition && node.hasClass('fade')) { + node.bind( + $.support.transition.end, + function (e) { + // Make sure we don't respond to other transitions events + // in the container element, e.g. from button elements: + if (e.target === node[0]) { + node.unbind($.support.transition.end); + deferred.resolveWith(node); + } + } + ).toggleClass('in'); + } else { + node.toggleClass('in'); + deferred.resolveWith(node); + } + return deferred; + }, + + _initButtonBarEventHandlers: function () { + var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'), + filesList = this.options.filesContainer, + ns = this.options.namespace; + fileUploadButtonBar.find('.start') + .bind('click.' + ns, function (e) { + e.preventDefault(); + filesList.find('.start button').click(); + }); + fileUploadButtonBar.find('.cancel') + .bind('click.' + ns, function (e) { + e.preventDefault(); + filesList.find('.cancel button').click(); + }); + fileUploadButtonBar.find('.delete') + .bind('click.' + ns, function (e) { + e.preventDefault(); + filesList.find('.delete input:checked') + .siblings('button').click(); + fileUploadButtonBar.find('.toggle') + .prop('checked', false); + }); + fileUploadButtonBar.find('.toggle') + .bind('change.' + ns, function (e) { + filesList.find('.delete input').prop( + 'checked', + $(this).is(':checked') + ); + }); + }, + + _destroyButtonBarEventHandlers: function () { + this.element.find('.fileupload-buttonbar button') + .unbind('click.' + this.options.namespace); + this.element.find('.fileupload-buttonbar .toggle') + .unbind('change.' + this.options.namespace); + }, + + _initEventHandlers: function () { + parentWidget.prototype._initEventHandlers.call(this); + var eventData = {fileupload: this}; + this.options.filesContainer + .delegate( + '.start button', + 'click.' + this.options.namespace, + eventData, + this._startHandler + ) + .delegate( + '.cancel button', + 'click.' + this.options.namespace, + eventData, + this._cancelHandler + ) + .delegate( + '.delete button', + 'click.' + this.options.namespace, + eventData, + this._deleteHandler + ); + this._initButtonBarEventHandlers(); + }, + + _destroyEventHandlers: function () { + var options = this.options; + this._destroyButtonBarEventHandlers(); + options.filesContainer + .undelegate('.start button', 'click.' + options.namespace) + .undelegate('.cancel button', 'click.' + options.namespace) + .undelegate('.delete button', 'click.' + options.namespace); + parentWidget.prototype._destroyEventHandlers.call(this); + }, + + _enableFileInputButton: function () { + this.element.find('.fileinput-button input') + .prop('disabled', false) + .parent().removeClass('disabled'); + }, + + _disableFileInputButton: function () { + this.element.find('.fileinput-button input') + .prop('disabled', true) + .parent().addClass('disabled'); + }, + + _initTemplates: function () { + var options = this.options; + options.templatesContainer = document.createElement( + options.filesContainer.prop('nodeName') + ); + if (tmpl) { + if (options.uploadTemplateId) { + options.uploadTemplate = tmpl(options.uploadTemplateId); + } + if (options.downloadTemplateId) { + options.downloadTemplate = tmpl(options.downloadTemplateId); + } + } + }, + + _initFilesContainer: function () { + var options = this.options; + if (options.filesContainer === undefined) { + options.filesContainer = this.element.find('.files'); + } else if (!(options.filesContainer instanceof $)) { + options.filesContainer = $(options.filesContainer); + } + }, + + _initSpecialOptions: function () { + parentWidget.prototype._initSpecialOptions.call(this); + this._initFilesContainer(); + this._initTemplates(); + }, + + _create: function () { + parentWidget.prototype._create.call(this); + this._refreshOptionsList.push( + 'filesContainer', + 'uploadTemplateId', + 'downloadTemplateId' + ); + if (!$.blueimpIP) { + this._processingQueue = $.Deferred().resolveWith(this).promise(); + this.resize = function () { + return this._processingQueue; + }; + } + }, + + enable: function () { + parentWidget.prototype.enable.call(this); + this.element.find('input, button').prop('disabled', false); + this._enableFileInputButton(); + }, + + disable: function () { + this.element.find('input, button').prop('disabled', true); + this._disableFileInputButton(); + parentWidget.prototype.disable.call(this); + } + + }); + +})); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.i18n.properties-1.0.9.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.i18n.properties-1.0.9.js new file mode 100644 index 000000000..573c4de93 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.i18n.properties-1.0.9.js @@ -0,0 +1,499 @@ +/****************************************************************************** + * jquery.i18n.properties + * + * Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and + * MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. + * + * @version 1.0.x + * @author Nuno Fernandes + * @url www.codingwithcoffee.com + * @inspiration Localisation assistance for jQuery (http://keith-wood.name/localisation.html) + * by Keith Wood (kbwood{at}iinet.com.au) June 2007 + * + *****************************************************************************/ + +// START olamy hack more AMD compliant +(function($, window) { + (function(factory){ + // Support module loading scenarios + if (typeof define === 'function' && define.amd){ + // AMD Anonymous Module + define(['jquery'], factory); + } else { + // No module loader (plain <script> tag) - put directly in global namespace + $.sammy = window.Sammy = factory($); + } + }) + +// END olamy hack +(function($) { +$.i18n = {}; + +/** Map holding bundle keys (if mode: 'map') */ +$.i18n.map = {}; + +/** + * Load and parse message bundle files (.properties), + * making bundles keys available as javascript variables. + * + * i18n files are named <name>.js, or <name>_<language>.js or <name>_<language>_<country>.js + * Where: + * The <language> argument is a valid ISO Language Code. These codes are the lower-case, + * two-letter codes as defined by ISO-639. You can find a full list of these codes at a + * number of sites, such as: http://www.loc.gov/standards/iso639-2/englangn.html + * The <country> argument is a valid ISO Country Code. These codes are the upper-case, + * two-letter codes as defined by ISO-3166. You can find a full list of these codes at a + * number of sites, such as: http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html + * + * Sample usage for a bundles/Messages.properties bundle: + * $.i18n.properties({ + * name: 'Messages', + * language: 'en_US', + * path: 'bundles' + * }); + * @param name (string/string[], optional) names of file to load (eg, 'Messages' or ['Msg1','Msg2']). Defaults to "Messages" + * @param language (string, optional) language/country code (eg, 'en', 'en_US', 'pt_PT'). if not specified, language reported by the browser will be used instead. + * @param path (string, optional) path of directory that contains file to load + * @param mode (string, optional) whether bundles keys are available as JavaScript variables/functions or as a map (eg, 'vars' or 'map') + * @param cache (boolean, optional) whether bundles should be cached by the browser, or forcibly reloaded on each page load. Defaults to false (i.e. forcibly reloaded) + * @param encoding (string, optional) the encoding to request for bundles. Property file resource bundles are specified to be in ISO-8859-1 format. Defaults to UTF-8 for backward compatibility. + * @param callback (function, optional) callback function to be called after script is terminated + */ +$.i18n.properties = function(settings) { + // set up settings + var defaults = { + name: 'Messages', + language: '', + path: '', + mode: 'vars', + cache: false, + encoding: 'UTF-8', + callback: null + }; + settings = $.extend(defaults, settings); + if(settings.language === null || settings.language == '') { + settings.language = $.i18n.browserLang(); + } + if(settings.language === null) {settings.language='';} + + // load and parse bundle files + var files = getFiles(settings.name); + for(i=0; i<files.length; i++) { + // 1. load base (eg, Messages.properties) + loadAndParseFile(settings.path + files[i] + '.properties', settings); + // 2. with language code (eg, Messages_pt.properties) + if(settings.language.length >= 2) { + loadAndParseFile(settings.path + files[i] + '_' + settings.language.substring(0, 2) +'.properties', settings); + } + // 3. with language code and country code (eg, Messages_pt_PT.properties) + if(settings.language.length >= 5) { + loadAndParseFile(settings.path + files[i] + '_' + settings.language.substring(0, 5) +'.properties', settings); + } + } + + // call callback + if(settings.callback){ settings.callback(); } +}; + + +/** + * When configured with mode: 'map', allows access to bundle values by specifying its key. + * Eg, jQuery.i18n.prop('com.company.bundles.menu_add') + */ +$.i18n.prop = function(key /* Add parameters as function arguments as necessary */) { + var value = $.i18n.map[key]; + if (value == null) { + if (window.archivaRuntimeInfo.logMissingI18n){ + $.get('restServices/archivaUiServices/runtimeInfoService/logMissingI18n?key='+encodeURIComponent(key)); + } + return '[' + key + ']'; + } + +// if(arguments.length < 2) // No arguments. +// //if(key == 'spv.lbl.modified') {alert(value);} +// return value; + +// if (!$.isArray(placeHolderValues)) { +// // If placeHolderValues is not an array, make it into one. +// placeHolderValues = [placeHolderValues]; +// for (var i=2; i<arguments.length; i++) +// placeHolderValues.push(arguments[i]); +// } + + // Place holder replacement + /** + * Tested with: + * test.t1=asdf ''{0}'' + * test.t2=asdf '{0}' '{1}'{1}'zxcv + * test.t3=This is \"a quote" 'a''{0}''s'd{fgh{ij' + * test.t4="'''{'0}''" {0}{a} + * test.t5="'''{0}'''" {1} + * test.t6=a {1} b {0} c + * test.t7=a 'quoted \\ s\ttringy' \t\t x + * + * Produces: + * test.t1, p1 ==> asdf 'p1' + * test.t2, p1 ==> asdf {0} {1}{1}zxcv + * test.t3, p1 ==> This is "a quote" a'{0}'sd{fgh{ij + * test.t4, p1 ==> "'{0}'" p1{a} + * test.t5, p1 ==> "'{0}'" {1} + * test.t6, p1 ==> a {1} b p1 c + * test.t6, p1, p2 ==> a p2 b p1 c + * test.t6, p1, p2, p3 ==> a p2 b p1 c + * test.t7 ==> a quoted \ s tringy x + */ + + var i; + if (typeof(value) == 'string') { + // Handle escape characters. Done separately from the tokenizing loop below because escape characters are + // active in quoted strings. + i = 0; + while ((i = value.indexOf('\\', i)) != -1) { + if (value[i+1] == 't') + value = value.substring(0, i) + '\t' + value.substring((i++) + 2); // tab + else if (value[i+1] == 'r') + value = value.substring(0, i) + '\r' + value.substring((i++) + 2); // return + else if (value[i+1] == 'n') + value = value.substring(0, i) + '\n' + value.substring((i++) + 2); // line feed + else if (value[i+1] == 'f') + value = value.substring(0, i) + '\f' + value.substring((i++) + 2); // form feed + else if (value[i+1] == '\\') + value = value.substring(0, i) + '\\' + value.substring((i++) + 2); // \ + else + value = value.substring(0, i) + value.substring(i+1); // Quietly drop the character + } + + // Lazily convert the string to a list of tokens. + var arr = [], j, index; + i = 0; + while (i < value.length) { + if (value[i] == '\'') { + // Handle quotes + if (i == value.length-1) + value = value.substring(0, i); // Silently drop the trailing quote + else if (value[i+1] == '\'') + value = value.substring(0, i) + value.substring(++i); // Escaped quote + else { + // Quoted string + j = i + 2; + while ((j = value.indexOf('\'', j)) != -1) { + if (j == value.length-1 || value[j+1] != '\'') { + // Found start and end quotes. Remove them + value = value.substring(0,i) + value.substring(i+1, j) + value.substring(j+1); + i = j - 1; + break; + } + else { + // Found a double quote, reduce to a single quote. + value = value.substring(0,j) + value.substring(++j); + } + } + + if (j == -1) { + // There is no end quote. Drop the start quote + value = value.substring(0,i) + value.substring(i+1); + } + } + } + else if (value[i] == '{') { + // Beginning of an unquoted place holder. + j = value.indexOf('}', i+1); + if (j == -1) + i++; // No end. Process the rest of the line. Java would throw an exception + else { + // Add 1 to the index so that it aligns with the function arguments. + index = parseInt(value.substring(i+1, j)); + if (!isNaN(index) && index >= 0) { + // Put the line thus far (if it isn't empty) into the array + var s = value.substring(0, i); + if (s != "") + arr.push(s); + // Put the parameter reference into the array + arr.push(index); + // Start the processing over again starting from the rest of the line. + i = 0; + value = value.substring(j+1); + } + else + i = j + 1; // Invalid parameter. Leave as is. + } + } + else + i++; + } + + // Put the remainder of the no-empty line into the array. + if (value != "") + arr.push(value); + value = arr; + + // Make the array the value for the entry. + $.i18n.map[key] = arr; + } + + if (value.length == 0) + return ""; + if (value.lengh == 1 && typeof(value[0]) == "string") + return value[0]; + + var s = ""; + for (i=0; i<value.length; i++) { + if (typeof(value[i]) == "string") + s += value[i]; + // Must be a number + else if (value[i] + 1 < arguments.length) + s += arguments[value[i] + 1]; + else + s += "{"+ value[i] +"}"; + } + + return s; +}; + +/** Language reported by browser, normalized code */ +$.i18n.browserLang = function() { + return normaliseLanguageCode(navigator.language /* Mozilla */ || navigator.userLanguage /* IE */); +} + + +/** Load and parse .properties files */ +loadAndParseFile = function (filename, settings) { + $.ajax({ + url: filename, + async: true, + cache: settings.cache, + contentType:'text/plain;charset='+ settings.encoding, + dataType: 'text', + success: function(data, status) { + parseData(data, settings.mode); + if(settings.callback){ settings.callback(); } + } + }); +} + +/** Parse .properties files */ +parseData = function(data, mode) { + var parsed = ''; + var parameters = data.split( /\n/ ); + var regPlaceHolder = /(\{\d+\})/g; + var regRepPlaceHolder = /\{(\d+)\}/g; + var unicodeRE = /(\\u.{4})/ig; + for(var i=0; i<parameters.length; i++ ) { + parameters[i] = parameters[i].replace( /^\s\s*/, '' ).replace( /\s\s*$/, '' ); // trim + if(parameters[i].length > 0 && parameters[i].match("^#")!="#") { // skip comments + var pair = parameters[i].split('='); + if(pair.length > 0) { + /** Process key & value */ + var name = unescape(pair[0]).replace( /^\s\s*/, '' ).replace( /\s\s*$/, '' ); // trim + var value = pair.length == 1 ? "" : pair[1]; + // process multi-line values + while(value.match(/\\$/)=="\\") { + value = value.substring(0, value.length - 1); + value += parameters[++i].replace( /\s\s*$/, '' ); // right trim + } + // Put values with embedded '='s back together + for(var s=2;s<pair.length;s++){ value +='=' + pair[s]; } + value = value.replace( /^\s\s*/, '' ).replace( /\s\s*$/, '' ); // trim + + /** Mode: bundle keys in a map */ + if(mode == 'map' || mode == 'both') { + // handle unicode chars possibly left out + var unicodeMatches = value.match(unicodeRE); + if(unicodeMatches) { + for(var u=0; u<unicodeMatches.length; u++) { + value = value.replace( unicodeMatches[u], unescapeUnicode(unicodeMatches[u])); + } + } + // add to map + $.i18n.map[name] = value; + // olamy hack replace . with _ + //var nName = name.replace (/\./g, '_'); + //$.i18n.map[nName] = value; + } + + /** Mode: bundle keys as vars/functions */ + if(mode == 'vars' || mode == 'both') { + value = value.replace( /"/g, '\\"' ); // escape quotation mark (") + + // make sure namespaced key exists (eg, 'some.key') + checkKeyNamespace(name); + + // value with variable substitutions + if(regPlaceHolder.test(value)) { + var parts = value.split(regPlaceHolder); + // process function args + var first = true; + var fnArgs = ''; + var usedArgs = []; + for(var p=0; p<parts.length; p++) { + if(regPlaceHolder.test(parts[p]) && (usedArgs.length == 0 || usedArgs.indexOf(parts[p]) == -1)) { + if(!first) {fnArgs += ',';} + fnArgs += parts[p].replace(regRepPlaceHolder, 'v$1'); + usedArgs.push(parts[p]); + first = false; + } + } + parsed += name + '=function(' + fnArgs + '){'; + // process function body + var fnExpr = '"' + value.replace(regRepPlaceHolder, '"+v$1+"') + '"'; + parsed += 'return ' + fnExpr + ';' + '};'; + + // simple value + }else{ + parsed += name+'="'+value+'";'; + } + } // END: Mode: bundle keys as vars/functions + } // END: if(pair.length > 0) + } // END: skip comments + } + eval(parsed); +} + +/** Make sure namespace exists (for keys with dots in name) */ +// TODO key parts that start with numbers quietly fail. i.e. month.short.1=Jan +function checkKeyNamespace(key) { + var regDot = /\./; + if(regDot.test(key)) { + var fullname = ''; + var names = key.split( /\./ ); + for(var i=0; i<names.length; i++) { + if(i>0) {fullname += '.';} + fullname += names[i]; + if(eval('typeof '+fullname+' == "undefined"')) { + eval(fullname + '={};'); + } + } + } +} + +/** Make sure filename is an array */ +function getFiles(names) { + return (names && names.constructor == Array) ? names : [names]; +} + +/** Ensure language code is in the format aa_AA. */ +function normaliseLanguageCode(lang) { + lang = lang.toLowerCase(); + if(lang.length > 3) { + lang = lang.substring(0, 3) + lang.substring(3).toUpperCase(); + } + return lang; +} + +/** Unescape unicode chars ('\u00e3') */ +function unescapeUnicode(str) { + // unescape unicode codes + var codes = []; + var code = parseInt(str.substr(2), 16); + if (code >= 0 && code < Math.pow(2, 16)) { + codes.push(code); + } + // convert codes to text + var unescaped = ''; + for (var i = 0; i < codes.length; ++i) { + unescaped += String.fromCharCode(codes[i]); + } + return unescaped; +} + +/* Cross-Browser Split 1.0.1 +(c) Steven Levithan <stevenlevithan.com>; MIT License +An ECMA-compliant, uniform cross-browser split method */ +var cbSplit; +// avoid running twice, which would break `cbSplit._nativeSplit`'s reference to the native `split` +if (!cbSplit) { + cbSplit = function(str, separator, limit) { + // if `separator` is not a regex, use the native `split` + if (Object.prototype.toString.call(separator) !== "[object RegExp]") { + if(typeof cbSplit._nativeSplit == "undefined") + return str.split(separator, limit); + else + return cbSplit._nativeSplit.call(str, separator, limit); + } + + var output = [], + lastLastIndex = 0, + flags = (separator.ignoreCase ? "i" : "") + + (separator.multiline ? "m" : "") + + (separator.sticky ? "y" : ""), + separator = RegExp(separator.source, flags + "g"), // make `global` and avoid `lastIndex` issues by working with a copy + separator2, match, lastIndex, lastLength; + + str = str + ""; // type conversion + if (!cbSplit._compliantExecNpcg) { + separator2 = RegExp("^" + separator.source + "$(?!\\s)", flags); // doesn't need /g or /y, but they don't hurt + } + + /* behavior for `limit`: if it's... + - `undefined`: no limit. + - `NaN` or zero: return an empty array. + - a positive number: use `Math.floor(limit)`. + - a negative number: no limit. + - other: type-convert, then use the above rules. */ + if (limit === undefined || +limit < 0) { + limit = Infinity; + } else { + limit = Math.floor(+limit); + if (!limit) { + return []; + } + } + + while (match = separator.exec(str)) { + lastIndex = match.index + match[0].length; // `separator.lastIndex` is not reliable cross-browser + + if (lastIndex > lastLastIndex) { + output.push(str.slice(lastLastIndex, match.index)); + + // fix browsers whose `exec` methods don't consistently return `undefined` for nonparticipating capturing groups + if (!cbSplit._compliantExecNpcg && match.length > 1) { + match[0].replace(separator2, function () { + for (var i = 1; i < arguments.length - 2; i++) { + if (arguments[i] === undefined) { + match[i] = undefined; + } + } + }); + } + + if (match.length > 1 && match.index < str.length) { + Array.prototype.push.apply(output, match.slice(1)); + } + + lastLength = match[0].length; + lastLastIndex = lastIndex; + + if (output.length >= limit) { + break; + } + } + + if (separator.lastIndex === match.index) { + separator.lastIndex++; // avoid an infinite loop + } + } + + if (lastLastIndex === str.length) { + if (lastLength || !separator.test("")) { + output.push(""); + } + } else { + output.push(str.slice(lastLastIndex)); + } + + return output.length > limit ? output.slice(0, limit) : output; + }; + + cbSplit._compliantExecNpcg = /()??/.exec("")[1] === undefined; // NPCG: nonparticipating capturing group + cbSplit._nativeSplit = String.prototype.split; + +} // end `if (!cbSplit)` +String.prototype.split = function (separator, limit) { + return cbSplit(this, separator, limit); +}; + +});// (jQuery); + +// START olamy hack more AMD compliant +})(jQuery, window); +// END olamy hack
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.iframe-transport-1.4.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.iframe-transport-1.4.js new file mode 100644 index 000000000..04a566230 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.iframe-transport-1.4.js @@ -0,0 +1,171 @@ +/* + * jQuery Iframe Transport Plugin 1.4 + * https://github.com/blueimp/jQuery-File-Upload + * + * Copyright 2011, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/MIT + */ + +/*jslint unparam: true, nomen: true */ +/*global define, window, document */ + +(function (factory) { + 'use strict'; + if (typeof define === 'function' && define.amd) { + // Register as an anonymous AMD module: + define(['jquery'], factory); + } else { + // Browser globals: + factory(window.jQuery); + } +}(function ($) { + 'use strict'; + + // Helper variable to create unique names for the transport iframes: + var counter = 0; + + // The iframe transport accepts three additional options: + // options.fileInput: a jQuery collection of file input fields + // options.paramName: the parameter name for the file form data, + // overrides the name property of the file input field(s), + // can be a string or an array of strings. + // options.formData: an array of objects with name and value properties, + // equivalent to the return data of .serializeArray(), e.g.: + // [{name: 'a', value: 1}, {name: 'b', value: 2}] + $.ajaxTransport('iframe', function (options) { + if (options.async && (options.type === 'POST' || options.type === 'GET')) { + var form, + iframe; + return { + send: function (_, completeCallback) { + form = $('<form style="display:none;"></form>'); + // javascript:false as initial iframe src + // prevents warning popups on HTTPS in IE6. + // IE versions below IE8 cannot set the name property of + // elements that have already been added to the DOM, + // so we set the name along with the iframe HTML markup: + iframe = $( + '<iframe src="javascript:false;" name="iframe-transport-' + + (counter += 1) + '"></iframe>' + ).bind('load', function () { + var fileInputClones, + paramNames = $.isArray(options.paramName) ? + options.paramName : [options.paramName]; + iframe + .unbind('load') + .bind('load', function () { + var response; + // Wrap in a try/catch block to catch exceptions thrown + // when trying to access cross-domain iframe contents: + try { + response = iframe.contents(); + // Google Chrome and Firefox do not throw an + // exception when calling iframe.contents() on + // cross-domain requests, so we unify the response: + if (!response.length || !response[0].firstChild) { + throw new Error(); + } + } catch (e) { + response = undefined; + } + // The complete callback returns the + // iframe content document as response object: + completeCallback( + 200, + 'success', + {'iframe': response} + ); + // Fix for IE endless progress bar activity bug + // (happens on form submits to iframe targets): + $('<iframe src="javascript:false;"></iframe>') + .appendTo(form); + form.remove(); + }); + form + .prop('target', iframe.prop('name')) + .prop('action', options.url) + .prop('method', options.type); + if (options.formData) { + $.each(options.formData, function (index, field) { + $('<input type="hidden"/>') + .prop('name', field.name) + .val(field.value) + .appendTo(form); + }); + } + if (options.fileInput && options.fileInput.length && + options.type === 'POST') { + fileInputClones = options.fileInput.clone(); + // Insert a clone for each file input field: + options.fileInput.after(function (index) { + return fileInputClones[index]; + }); + if (options.paramName) { + options.fileInput.each(function (index) { + $(this).prop( + 'name', + paramNames[index] || options.paramName + ); + }); + } + // Appending the file input fields to the hidden form + // removes them from their original location: + form + .append(options.fileInput) + .prop('enctype', 'multipart/form-data') + // enctype must be set as encoding for IE: + .prop('encoding', 'multipart/form-data'); + } + form.submit(); + // Insert the file input fields at their original location + // by replacing the clones with the originals: + if (fileInputClones && fileInputClones.length) { + options.fileInput.each(function (index, input) { + var clone = $(fileInputClones[index]); + $(input).prop('name', clone.prop('name')); + clone.replaceWith(input); + }); + } + }); + form.append(iframe).appendTo(document.body); + }, + abort: function () { + if (iframe) { + // javascript:false as iframe src aborts the request + // and prevents warning popups on HTTPS in IE6. + // concat is used to avoid the "Script URL" JSLint error: + iframe + .unbind('load') + .prop('src', 'javascript'.concat(':false;')); + } + if (form) { + form.remove(); + } + } + }; + } + }); + + // The iframe transport returns the iframe content document as response. + // The following adds converters from iframe to text, json, html, and script: + $.ajaxSetup({ + converters: { + 'iframe text': function (iframe) { + return $(iframe[0].body).text(); + }, + 'iframe json': function (iframe) { + return $.parseJSON($(iframe[0].body).text()); + }, + 'iframe html': function (iframe) { + return $(iframe[0].body).html(); + }, + 'iframe script': function (iframe) { + return $.globalEval($(iframe[0].body).text()); + } + } + }); + +})); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.json-2.3.min.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.json-2.3.min.js new file mode 100644 index 000000000..4e4e38680 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.json-2.3.min.js @@ -0,0 +1,23 @@ + +(function($){var escapeable=/["\\\x00-\x1f\x7f-\x9f]/g,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};$.toJSON=typeof JSON==='object'&&JSON.stringify?JSON.stringify:function(o){if(o===null){return'null';} +var type=typeof o;if(type==='undefined'){return undefined;} +if(type==='number'||type==='boolean'){return''+o;} +if(type==='string'){return $.quoteString(o);} +if(type==='object'){if(typeof o.toJSON==='function'){return $.toJSON(o.toJSON());} +if(o.constructor===Date){var month=o.getUTCMonth()+1,day=o.getUTCDate(),year=o.getUTCFullYear(),hours=o.getUTCHours(),minutes=o.getUTCMinutes(),seconds=o.getUTCSeconds(),milli=o.getUTCMilliseconds();if(month<10){month='0'+month;} +if(day<10){day='0'+day;} +if(hours<10){hours='0'+hours;} +if(minutes<10){minutes='0'+minutes;} +if(seconds<10){seconds='0'+seconds;} +if(milli<100){milli='0'+milli;} +if(milli<10){milli='0'+milli;} +return'"'+year+'-'+month+'-'+day+'T'+ +hours+':'+minutes+':'+seconds+'.'+milli+'Z"';} +if(o.constructor===Array){var ret=[];for(var i=0;i<o.length;i++){ret.push($.toJSON(o[i])||'null');} +return'['+ret.join(',')+']';} +var name,val,pairs=[];for(var k in o){type=typeof k;if(type==='number'){name='"'+k+'"';}else if(type==='string'){name=$.quoteString(k);}else{continue;} +type=typeof o[k];if(type==='function'||type==='undefined'){continue;} +val=$.toJSON(o[k]);pairs.push(name+':'+val);} +return'{'+pairs.join(',')+'}';}};$.evalJSON=typeof JSON==='object'&&JSON.parse?JSON.parse:function(src){return eval('('+src+')');};$.secureEvalJSON=typeof JSON==='object'&&JSON.parse?JSON.parse:function(src){var filtered=src.replace(/\\["\\\/bfnrtu]/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,'');if(/^[\],:{}\s]*$/.test(filtered)){return eval('('+src+')');}else{throw new SyntaxError('Error parsing JSON, source is not valid.');}};$.quoteString=function(string){if(string.match(escapeable)){return'"'+string.replace(escapeable,function(a){var c=meta[a];if(typeof c==='string'){return c;} +c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16);})+'"';} +return'"'+string+'"';};})(jQuery);
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.tmpl.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.tmpl.js new file mode 100644 index 000000000..c10fc8f75 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.tmpl.js @@ -0,0 +1,492 @@ +/*! + * jQuery Templates Plugin 1.0.0pre + * http://github.com/jquery/jquery-tmpl + * Requires jQuery 1.4.2 + * + * Copyright Software Freedom Conservancy, Inc. + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + */ + +define("jquery.tmpl",["jquery"], +function() { + +//(function( jQuery, undefined ){ + var oldManip = jQuery.fn.domManip, tmplItmAtt = "_tmplitem", htmlExpr = /^[^<]*(<[\w\W]+>)[^>]*$|\{\{\! /, + newTmplItems = {}, wrappedItems = {}, appendToTmplItems, topTmplItem = { key: 0, data: {} }, itemKey = 0, cloneIndex = 0, stack = []; + + function newTmplItem( options, parentItem, fn, data ) { + // Returns a template item data structure for a new rendered instance of a template (a 'template item'). + // The content field is a hierarchical array of strings and nested items (to be + // removed and replaced by nodes field of dom elements, once inserted in DOM). + var newItem = { + data: data || (data === 0 || data === false) ? data : (parentItem ? parentItem.data : {}), + _wrap: parentItem ? parentItem._wrap : null, + tmpl: null, + parent: parentItem || null, + nodes: [], + calls: tiCalls, + nest: tiNest, + wrap: tiWrap, + html: tiHtml, + update: tiUpdate + }; + if ( options ) { + jQuery.extend( newItem, options, { nodes: [], parent: parentItem }); + } + if ( fn ) { + // Build the hierarchical content to be used during insertion into DOM + newItem.tmpl = fn; + newItem._ctnt = newItem._ctnt || newItem.tmpl( jQuery, newItem ); + newItem.key = ++itemKey; + // Keep track of new template item, until it is stored as jQuery Data on DOM element + (stack.length ? wrappedItems : newTmplItems)[itemKey] = newItem; + } + return newItem; + } + + // Override appendTo etc., in order to provide support for targeting multiple elements. (This code would disappear if integrated in jquery core). + jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" + }, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var ret = [], insert = jQuery( selector ), elems, i, l, tmplItems, + parent = this.length === 1 && this[0].parentNode; + + appendToTmplItems = newTmplItems || {}; + if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) { + insert[ original ]( this[0] ); + ret = this; + } else { + for ( i = 0, l = insert.length; i < l; i++ ) { + cloneIndex = i; + elems = (i > 0 ? this.clone(true) : this).get(); + jQuery( insert[i] )[ original ]( elems ); + ret = ret.concat( elems ); + } + cloneIndex = 0; + ret = this.pushStack( ret, name, insert.selector ); + } + tmplItems = appendToTmplItems; + appendToTmplItems = null; + jQuery.tmpl.complete( tmplItems ); + return ret; + }; + }); + + jQuery.fn.extend({ + // Use first wrapped element as template markup. + // Return wrapped set of template items, obtained by rendering template against data. + tmpl: function( data, options, parentItem ) { + return jQuery.tmpl( this[0], data, options, parentItem ); + }, + + // Find which rendered template item the first wrapped DOM element belongs to + tmplItem: function() { + return jQuery.tmplItem( this[0] ); + }, + + // Consider the first wrapped element as a template declaration, and get the compiled template or store it as a named template. + template: function( name ) { + return jQuery.template( name, this[0] ); + }, + + domManip: function( args, table, callback, options ) { + if ( args[0] && jQuery.isArray( args[0] )) { + var dmArgs = jQuery.makeArray( arguments ), elems = args[0], elemsLength = elems.length, i = 0, tmplItem; + while ( i < elemsLength && !(tmplItem = jQuery.data( elems[i++], "tmplItem" ))) {} + if ( tmplItem && cloneIndex ) { + dmArgs[2] = function( fragClone ) { + // Handler called by oldManip when rendered template has been inserted into DOM. + jQuery.tmpl.afterManip( this, fragClone, callback ); + }; + } + oldManip.apply( this, dmArgs ); + } else { + oldManip.apply( this, arguments ); + } + cloneIndex = 0; + if ( !appendToTmplItems ) { + jQuery.tmpl.complete( newTmplItems ); + } + return this; + } + }); + + jQuery.extend({ + // Return wrapped set of template items, obtained by rendering template against data. + tmpl: function( tmpl, data, options, parentItem ) { + var ret, topLevel = !parentItem; + if ( topLevel ) { + // This is a top-level tmpl call (not from a nested template using {{tmpl}}) + parentItem = topTmplItem; + tmpl = jQuery.template[tmpl] || jQuery.template( null, tmpl ); + wrappedItems = {}; // Any wrapped items will be rebuilt, since this is top level + } else if ( !tmpl ) { + // The template item is already associated with DOM - this is a refresh. + // Re-evaluate rendered template for the parentItem + tmpl = parentItem.tmpl; + newTmplItems[parentItem.key] = parentItem; + parentItem.nodes = []; + if ( parentItem.wrapped ) { + updateWrapped( parentItem, parentItem.wrapped ); + } + // Rebuild, without creating a new template item + return jQuery( build( parentItem, null, parentItem.tmpl( jQuery, parentItem ) )); + } + if ( !tmpl ) { + return []; // Could throw... + } + if ( typeof data === "function" ) { + data = data.call( parentItem || {} ); + } + if ( options && options.wrapped ) { + updateWrapped( options, options.wrapped ); + } + ret = jQuery.isArray( data ) ? + jQuery.map( data, function( dataItem ) { + return dataItem ? newTmplItem( options, parentItem, tmpl, dataItem ) : null; + }) : + [ newTmplItem( options, parentItem, tmpl, data ) ]; + return topLevel ? jQuery( build( parentItem, null, ret ) ) : ret; + }, + + // Return rendered template item for an element. + tmplItem: function( elem ) { + var tmplItem; + if ( elem instanceof jQuery ) { + elem = elem[0]; + } + while ( elem && elem.nodeType === 1 && !(tmplItem = jQuery.data( elem, "tmplItem" )) && (elem = elem.parentNode) ) {} + return tmplItem || topTmplItem; + }, + + // Set: + // Use $.template( name, tmpl ) to cache a named template, + // where tmpl is a template string, a script element or a jQuery instance wrapping a script element, etc. + // Use $( "selector" ).template( name ) to provide access by name to a script block template declaration. + + // Get: + // Use $.template( name ) to access a cached template. + // Also $( selectorToScriptBlock ).template(), or $.template( null, templateString ) + // will return the compiled template, without adding a name reference. + // If templateString includes at least one HTML tag, $.template( templateString ) is equivalent + // to $.template( null, templateString ) + template: function( name, tmpl ) { + if (tmpl) { + // Compile template and associate with name + if ( typeof tmpl === "string" ) { + // This is an HTML string being passed directly in. + tmpl = buildTmplFn( tmpl ); + } else if ( tmpl instanceof jQuery ) { + tmpl = tmpl[0] || {}; + } + if ( tmpl.nodeType ) { + // If this is a template block, use cached copy, or generate tmpl function and cache. + tmpl = jQuery.data( tmpl, "tmpl" ) || jQuery.data( tmpl, "tmpl", buildTmplFn( tmpl.innerHTML )); + // Issue: In IE, if the container element is not a script block, the innerHTML will remove quotes from attribute values whenever the value does not include white space. + // This means that foo="${x}" will not work if the value of x includes white space: foo="${x}" -> foo=value of x. + // To correct this, include space in tag: foo="${ x }" -> foo="value of x" + } + return typeof name === "string" ? (jQuery.template[name] = tmpl) : tmpl; + } + // Return named compiled template + return name ? (typeof name !== "string" ? jQuery.template( null, name ): + (jQuery.template[name] || + // If not in map, and not containing at least on HTML tag, treat as a selector. + // (If integrated with core, use quickExpr.exec) + jQuery.template( null, htmlExpr.test( name ) ? name : jQuery( name )))) : null; + }, + + encode: function( text ) { + // Do HTML encoding replacing < > & and ' and " by corresponding entities. + return ("" + text).split("<").join("<").split(">").join(">").split('"').join(""").split("'").join("'"); + } + }); + + jQuery.extend( jQuery.tmpl, { + tag: { + "tmpl": { + _default: { $2: "null" }, + open: "if($notnull_1){__=__.concat($item.nest($1,$2));}" + // tmpl target parameter can be of type function, so use $1, not $1a (so not auto detection of functions) + // This means that {{tmpl foo}} treats foo as a template (which IS a function). + // Explicit parens can be used if foo is a function that returns a template: {{tmpl foo()}}. + }, + "wrap": { + _default: { $2: "null" }, + open: "$item.calls(__,$1,$2);__=[];", + close: "call=$item.calls();__=call._.concat($item.wrap(call,__));" + }, + "each": { + _default: { $2: "$index, $value" }, + open: "if($notnull_1){$.each($1a,function($2){with(this){", + close: "}});}" + }, + "if": { + open: "if(($notnull_1) && $1a){", + close: "}" + }, + "else": { + _default: { $1: "true" }, + open: "}else if(($notnull_1) && $1a){" + }, + "html": { + // Unecoded expression evaluation. + open: "if($notnull_1){__.push($1a);}" + }, + "=": { + // Encoded expression evaluation. Abbreviated form is ${}. + _default: { $1: "$data" }, + open: "if($notnull_1){__.push($.encode($1a));}" + }, + "!": { + // Comment tag. Skipped by parser + open: "" + } + }, + + // This stub can be overridden, e.g. in jquery.tmplPlus for providing rendered events + complete: function( items ) { + newTmplItems = {}; + }, + + // Call this from code which overrides domManip, or equivalent + // Manage cloning/storing template items etc. + afterManip: function afterManip( elem, fragClone, callback ) { + // Provides cloned fragment ready for fixup prior to and after insertion into DOM + var content = fragClone.nodeType === 11 ? + jQuery.makeArray(fragClone.childNodes) : + fragClone.nodeType === 1 ? [fragClone] : []; + + // Return fragment to original caller (e.g. append) for DOM insertion + callback.call( elem, fragClone ); + + // Fragment has been inserted:- Add inserted nodes to tmplItem data structure. Replace inserted element annotations by jQuery.data. + storeTmplItems( content ); + cloneIndex++; + } + }); + + //========================== Private helper functions, used by code above ========================== + + function build( tmplItem, nested, content ) { + // Convert hierarchical content into flat string array + // and finally return array of fragments ready for DOM insertion + var frag, ret = content ? jQuery.map( content, function( item ) { + return (typeof item === "string") ? + // Insert template item annotations, to be converted to jQuery.data( "tmplItem" ) when elems are inserted into DOM. + (tmplItem.key ? item.replace( /(<\w+)(?=[\s>])(?![^>]*_tmplitem)([^>]*)/g, "$1 " + tmplItmAtt + "=\"" + tmplItem.key + "\" $2" ) : item) : + // This is a child template item. Build nested template. + build( item, tmplItem, item._ctnt ); + }) : + // If content is not defined, insert tmplItem directly. Not a template item. May be a string, or a string array, e.g. from {{html $item.html()}}. + tmplItem; + if ( nested ) { + return ret; + } + + // top-level template + ret = ret.join(""); + + // Support templates which have initial or final text nodes, or consist only of text + // Also support HTML entities within the HTML markup. + ret.replace( /^\s*([^<\s][^<]*)?(<[\w\W]+>)([^>]*[^>\s])?\s*$/, function( all, before, middle, after) { + frag = jQuery( middle ).get(); + + storeTmplItems( frag ); + if ( before ) { + frag = unencode( before ).concat(frag); + } + if ( after ) { + frag = frag.concat(unencode( after )); + } + }); + return frag ? frag : unencode( ret ); + } + + function unencode( text ) { + // Use createElement, since createTextNode will not render HTML entities correctly + var el = document.createElement( "div" ); + el.innerHTML = text; + return jQuery.makeArray(el.childNodes); + } + + // Generate a reusable function that will serve to render a template against data + function buildTmplFn( markup ) { + return new Function("jQuery","$item", + // Use the variable __ to hold a string array while building the compiled template. (See https://github.com/jquery/jquery-tmpl/issues#issue/10). + "var $=jQuery,call,__=[],$data=$item.data;" + + + // Introduce the data as local variables using with(){} + "with($data){__.push('" + + + // Convert the template into pure JavaScript + jQuery.trim(markup) + .replace( /([\\'])/g, "\\$1" ) + .replace( /[\r\t\n]/g, " " ) + .replace( /\$\{([^\}]*)\}/g, "{{= $1}}" ) + .replace( /\{\{(\/?)(\w+|.)(?:\(((?:[^\}]|\}(?!\}))*?)?\))?(?:\s+(.*?)?)?(\(((?:[^\}]|\}(?!\}))*?)\))?\s*\}\}/g, + function( all, slash, type, fnargs, target, parens, args ) { + var tag = jQuery.tmpl.tag[ type ], def, expr, exprAutoFnDetect; + if ( !tag ) { + throw "Unknown template tag: " + type; + } + def = tag._default || []; + if ( parens && !/\w$/.test(target)) { + target += parens; + parens = ""; + } + if ( target ) { + target = unescape( target ); + args = args ? ("," + unescape( args ) + ")") : (parens ? ")" : ""); + // Support for target being things like a.toLowerCase(); + // In that case don't call with template item as 'this' pointer. Just evaluate... + expr = parens ? (target.indexOf(".") > -1 ? target + unescape( parens ) : ("(" + target + ").call($item" + args)) : target; + exprAutoFnDetect = parens ? expr : "(typeof(" + target + ")==='function'?(" + target + ").call($item):(" + target + "))"; + } else { + exprAutoFnDetect = expr = def.$1 || "null"; + } + fnargs = unescape( fnargs ); + return "');" + + tag[ slash ? "close" : "open" ] + .split( "$notnull_1" ).join( target ? "typeof(" + target + ")!=='undefined' && (" + target + ")!=null" : "true" ) + .split( "$1a" ).join( exprAutoFnDetect ) + .split( "$1" ).join( expr ) + .split( "$2" ).join( fnargs || def.$2 || "" ) + + "__.push('"; + }) + + "');}return __;" + ); + } + function updateWrapped( options, wrapped ) { + // Build the wrapped content. + options._wrap = build( options, true, + // Suport imperative scenario in which options.wrapped can be set to a selector or an HTML string. + jQuery.isArray( wrapped ) ? wrapped : [htmlExpr.test( wrapped ) ? wrapped : jQuery( wrapped ).html()] + ).join(""); + } + + function unescape( args ) { + return args ? args.replace( /\\'/g, "'").replace(/\\\\/g, "\\" ) : null; + } + function outerHtml( elem ) { + var div = document.createElement("div"); + div.appendChild( elem.cloneNode(true) ); + return div.innerHTML; + } + + // Store template items in jQuery.data(), ensuring a unique tmplItem data data structure for each rendered template instance. + function storeTmplItems( content ) { + var keySuffix = "_" + cloneIndex, elem, elems, newClonedItems = {}, i, l, m; + for ( i = 0, l = content.length; i < l; i++ ) { + if ( (elem = content[i]).nodeType !== 1 ) { + continue; + } + elems = elem.getElementsByTagName("*"); + for ( m = elems.length - 1; m >= 0; m-- ) { + processItemKey( elems[m] ); + } + processItemKey( elem ); + } + function processItemKey( el ) { + var pntKey, pntNode = el, pntItem, tmplItem, key; + // Ensure that each rendered template inserted into the DOM has its own template item, + if ( (key = el.getAttribute( tmplItmAtt ))) { + while ( pntNode.parentNode && (pntNode = pntNode.parentNode).nodeType === 1 && !(pntKey = pntNode.getAttribute( tmplItmAtt ))) { } + if ( pntKey !== key ) { + // The next ancestor with a _tmplitem expando is on a different key than this one. + // So this is a top-level element within this template item + // Set pntNode to the key of the parentNode, or to 0 if pntNode.parentNode is null, or pntNode is a fragment. + pntNode = pntNode.parentNode ? (pntNode.nodeType === 11 ? 0 : (pntNode.getAttribute( tmplItmAtt ) || 0)) : 0; + if ( !(tmplItem = newTmplItems[key]) ) { + // The item is for wrapped content, and was copied from the temporary parent wrappedItem. + tmplItem = wrappedItems[key]; + tmplItem = newTmplItem( tmplItem, newTmplItems[pntNode]||wrappedItems[pntNode] ); + tmplItem.key = ++itemKey; + newTmplItems[itemKey] = tmplItem; + } + if ( cloneIndex ) { + cloneTmplItem( key ); + } + } + el.removeAttribute( tmplItmAtt ); + } else if ( cloneIndex && (tmplItem = jQuery.data( el, "tmplItem" )) ) { + // This was a rendered element, cloned during append or appendTo etc. + // TmplItem stored in jQuery data has already been cloned in cloneCopyEvent. We must replace it with a fresh cloned tmplItem. + cloneTmplItem( tmplItem.key ); + newTmplItems[tmplItem.key] = tmplItem; + pntNode = jQuery.data( el.parentNode, "tmplItem" ); + pntNode = pntNode ? pntNode.key : 0; + } + if ( tmplItem ) { + pntItem = tmplItem; + // Find the template item of the parent element. + // (Using !=, not !==, since pntItem.key is number, and pntNode may be a string) + while ( pntItem && pntItem.key != pntNode ) { + // Add this element as a top-level node for this rendered template item, as well as for any + // ancestor items between this item and the item of its parent element + pntItem.nodes.push( el ); + pntItem = pntItem.parent; + } + // Delete content built during rendering - reduce API surface area and memory use, and avoid exposing of stale data after rendering... + delete tmplItem._ctnt; + delete tmplItem._wrap; + // Store template item as jQuery data on the element + jQuery.data( el, "tmplItem", tmplItem ); + } + function cloneTmplItem( key ) { + key = key + keySuffix; + tmplItem = newClonedItems[key] = + (newClonedItems[key] || newTmplItem( tmplItem, newTmplItems[tmplItem.parent.key + keySuffix] || tmplItem.parent )); + } + } + } + + //---- Helper functions for template item ---- + + function tiCalls( content, tmpl, data, options ) { + if ( !content ) { + return stack.pop(); + } + stack.push({ _: content, tmpl: tmpl, item:this, data: data, options: options }); + } + + function tiNest( tmpl, data, options ) { + // nested template, using {{tmpl}} tag + return jQuery.tmpl( jQuery.template( tmpl ), data, options, this ); + } + + function tiWrap( call, wrapped ) { + // nested template, using {{wrap}} tag + var options = call.options || {}; + options.wrapped = wrapped; + // Apply the template, which may incorporate wrapped content, + return jQuery.tmpl( jQuery.template( call.tmpl ), call.data, options, call.item ); + } + + function tiHtml( filter, textOnly ) { + var wrapped = this._wrap; + return jQuery.map( + jQuery( jQuery.isArray( wrapped ) ? wrapped.join("") : wrapped ).filter( filter || "*" ), + function(e) { + return textOnly ? + e.innerText || e.textContent : + e.outerHTML || outerHtml(e); + }); + } + + function tiUpdate() { + var coll = this.nodes; + jQuery.tmpl( null, null, null, this).insertBefore( coll[0] ); + jQuery( coll ).remove(); + } +//})( jQuery ); + + + +});
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.ui.widget-1.9.2.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.ui.widget-1.9.2.js new file mode 100755 index 000000000..067476d97 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.ui.widget-1.9.2.js @@ -0,0 +1,528 @@ +/*! + * jQuery UI Widget 1.9.2 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/jQuery.widget/ + */ +(function( $, undefined ) { + +var uuid = 0, + slice = Array.prototype.slice, + _cleanData = $.cleanData; +$.cleanData = function( elems ) { + for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + try { + $( elem ).triggerHandler( "remove" ); + // http://bugs.jquery.com/ticket/8235 + } catch( e ) {} + } + _cleanData( elems ); +}; + +$.widget = function( name, base, prototype ) { + var fullName, existingConstructor, constructor, basePrototype, + namespace = name.split( "." )[ 0 ]; + + name = name.split( "." )[ 1 ]; + fullName = namespace + "-" + name; + + if ( !prototype ) { + prototype = base; + base = $.Widget; + } + + // create selector for plugin + $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { + return !!$.data( elem, fullName ); + }; + + $[ namespace ] = $[ namespace ] || {}; + existingConstructor = $[ namespace ][ name ]; + constructor = $[ namespace ][ name ] = function( options, element ) { + // allow instantiation without "new" keyword + if ( !this._createWidget ) { + return new constructor( options, element ); + } + + // allow instantiation without initializing for simple inheritance + // must use "new" keyword (the code above always passes args) + if ( arguments.length ) { + this._createWidget( options, element ); + } + }; + // extend with the existing constructor to carry over any static properties + $.extend( constructor, existingConstructor, { + version: prototype.version, + // copy the object used to create the prototype in case we need to + // redefine the widget later + _proto: $.extend( {}, prototype ), + // track widgets that inherit from this widget in case this widget is + // redefined after a widget inherits from it + _childConstructors: [] + }); + + basePrototype = new base(); + // we need to make the options hash a property directly on the new instance + // otherwise we'll modify the options hash on the prototype that we're + // inheriting from + basePrototype.options = $.widget.extend( {}, basePrototype.options ); + $.each( prototype, function( prop, value ) { + if ( $.isFunction( value ) ) { + prototype[ prop ] = (function() { + var _super = function() { + return base.prototype[ prop ].apply( this, arguments ); + }, + _superApply = function( args ) { + return base.prototype[ prop ].apply( this, args ); + }; + return function() { + var __super = this._super, + __superApply = this._superApply, + returnValue; + + this._super = _super; + this._superApply = _superApply; + + returnValue = value.apply( this, arguments ); + + this._super = __super; + this._superApply = __superApply; + + return returnValue; + }; + })(); + } + }); + constructor.prototype = $.widget.extend( basePrototype, { + // TODO: remove support for widgetEventPrefix + // always use the name + a colon as the prefix, e.g., draggable:start + // don't prefix for widgets that aren't DOM-based + widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name + }, prototype, { + constructor: constructor, + namespace: namespace, + widgetName: name, + // TODO remove widgetBaseClass, see #8155 + widgetBaseClass: fullName, + widgetFullName: fullName + }); + + // If this widget is being redefined then we need to find all widgets that + // are inheriting from it and redefine all of them so that they inherit from + // the new version of this widget. We're essentially trying to replace one + // level in the prototype chain. + if ( existingConstructor ) { + $.each( existingConstructor._childConstructors, function( i, child ) { + var childPrototype = child.prototype; + + // redefine the child widget using the same prototype that was + // originally used, but inherit from the new version of the base + $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); + }); + // remove the list of existing child constructors from the old constructor + // so the old child constructors can be garbage collected + delete existingConstructor._childConstructors; + } else { + base._childConstructors.push( constructor ); + } + + $.widget.bridge( name, constructor ); +}; + +$.widget.extend = function( target ) { + var input = slice.call( arguments, 1 ), + inputIndex = 0, + inputLength = input.length, + key, + value; + for ( ; inputIndex < inputLength; inputIndex++ ) { + for ( key in input[ inputIndex ] ) { + value = input[ inputIndex ][ key ]; + if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { + // Clone objects + if ( $.isPlainObject( value ) ) { + target[ key ] = $.isPlainObject( target[ key ] ) ? + $.widget.extend( {}, target[ key ], value ) : + // Don't extend strings, arrays, etc. with objects + $.widget.extend( {}, value ); + // Copy everything else by reference + } else { + target[ key ] = value; + } + } + } + } + return target; +}; + +$.widget.bridge = function( name, object ) { + var fullName = object.prototype.widgetFullName || name; + $.fn[ name ] = function( options ) { + var isMethodCall = typeof options === "string", + args = slice.call( arguments, 1 ), + returnValue = this; + + // allow multiple hashes to be passed on init + options = !isMethodCall && args.length ? + $.widget.extend.apply( null, [ options ].concat(args) ) : + options; + + if ( isMethodCall ) { + this.each(function() { + var methodValue, + instance = $.data( this, fullName ); + if ( !instance ) { + return $.error( "cannot call methods on " + name + " prior to initialization; " + + "attempted to call method '" + options + "'" ); + } + if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { + return $.error( "no such method '" + options + "' for " + name + " widget instance" ); + } + methodValue = instance[ options ].apply( instance, args ); + if ( methodValue !== instance && methodValue !== undefined ) { + returnValue = methodValue && methodValue.jquery ? + returnValue.pushStack( methodValue.get() ) : + methodValue; + return false; + } + }); + } else { + this.each(function() { + var instance = $.data( this, fullName ); + if ( instance ) { + instance.option( options || {} )._init(); + } else { + $.data( this, fullName, new object( options, this ) ); + } + }); + } + + return returnValue; + }; +}; + +$.Widget = function( /* options, element */ ) {}; +$.Widget._childConstructors = []; + +$.Widget.prototype = { + widgetName: "widget", + widgetEventPrefix: "", + defaultElement: "<div>", + options: { + disabled: false, + + // callbacks + create: null + }, + _createWidget: function( options, element ) { + element = $( element || this.defaultElement || this )[ 0 ]; + this.element = $( element ); + this.uuid = uuid++; + this.eventNamespace = "." + this.widgetName + this.uuid; + this.options = $.widget.extend( {}, + this.options, + this._getCreateOptions(), + options ); + + this.bindings = $(); + this.hoverable = $(); + this.focusable = $(); + + if ( element !== this ) { + // 1.9 BC for #7810 + // TODO remove dual storage + $.data( element, this.widgetName, this ); + $.data( element, this.widgetFullName, this ); + this._on( true, this.element, { + remove: function( event ) { + if ( event.target === element ) { + this.destroy(); + } + } + }); + this.document = $( element.style ? + // element within the document + element.ownerDocument : + // element is window or document + element.document || element ); + this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); + } + + this._create(); + this._trigger( "create", null, this._getCreateEventData() ); + this._init(); + }, + _getCreateOptions: $.noop, + _getCreateEventData: $.noop, + _create: $.noop, + _init: $.noop, + + destroy: function() { + this._destroy(); + // we can probably remove the unbind calls in 2.0 + // all event bindings should go through this._on() + this.element + .unbind( this.eventNamespace ) + // 1.9 BC for #7810 + // TODO remove dual storage + .removeData( this.widgetName ) + .removeData( this.widgetFullName ) + // support: jquery <1.6.3 + // http://bugs.jquery.com/ticket/9413 + .removeData( $.camelCase( this.widgetFullName ) ); + this.widget() + .unbind( this.eventNamespace ) + .removeAttr( "aria-disabled" ) + .removeClass( + this.widgetFullName + "-disabled " + + "ui-state-disabled" ); + + // clean up events and states + this.bindings.unbind( this.eventNamespace ); + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + }, + _destroy: $.noop, + + widget: function() { + return this.element; + }, + + option: function( key, value ) { + var options = key, + parts, + curOption, + i; + + if ( arguments.length === 0 ) { + // don't return a reference to the internal hash + return $.widget.extend( {}, this.options ); + } + + if ( typeof key === "string" ) { + // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } + options = {}; + parts = key.split( "." ); + key = parts.shift(); + if ( parts.length ) { + curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); + for ( i = 0; i < parts.length - 1; i++ ) { + curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; + curOption = curOption[ parts[ i ] ]; + } + key = parts.pop(); + if ( value === undefined ) { + return curOption[ key ] === undefined ? null : curOption[ key ]; + } + curOption[ key ] = value; + } else { + if ( value === undefined ) { + return this.options[ key ] === undefined ? null : this.options[ key ]; + } + options[ key ] = value; + } + } + + this._setOptions( options ); + + return this; + }, + _setOptions: function( options ) { + var key; + + for ( key in options ) { + this._setOption( key, options[ key ] ); + } + + return this; + }, + _setOption: function( key, value ) { + this.options[ key ] = value; + + if ( key === "disabled" ) { + this.widget() + .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) + .attr( "aria-disabled", value ); + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + } + + return this; + }, + + enable: function() { + return this._setOption( "disabled", false ); + }, + disable: function() { + return this._setOption( "disabled", true ); + }, + + _on: function( suppressDisabledCheck, element, handlers ) { + var delegateElement, + instance = this; + + // no suppressDisabledCheck flag, shuffle arguments + if ( typeof suppressDisabledCheck !== "boolean" ) { + handlers = element; + element = suppressDisabledCheck; + suppressDisabledCheck = false; + } + + // no element argument, shuffle and use this.element + if ( !handlers ) { + handlers = element; + element = this.element; + delegateElement = this.widget(); + } else { + // accept selectors, DOM elements + element = delegateElement = $( element ); + this.bindings = this.bindings.add( element ); + } + + $.each( handlers, function( event, handler ) { + function handlerProxy() { + // allow widgets to customize the disabled handling + // - disabled as an array instead of boolean + // - disabled class as method for disabling individual parts + if ( !suppressDisabledCheck && + ( instance.options.disabled === true || + $( this ).hasClass( "ui-state-disabled" ) ) ) { + return; + } + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + + // copy the guid so direct unbinding works + if ( typeof handler !== "string" ) { + handlerProxy.guid = handler.guid = + handler.guid || handlerProxy.guid || $.guid++; + } + + var match = event.match( /^(\w+)\s*(.*)$/ ), + eventName = match[1] + instance.eventNamespace, + selector = match[2]; + if ( selector ) { + delegateElement.delegate( selector, eventName, handlerProxy ); + } else { + element.bind( eventName, handlerProxy ); + } + }); + }, + + _off: function( element, eventName ) { + eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; + element.unbind( eventName ).undelegate( eventName ); + }, + + _delay: function( handler, delay ) { + function handlerProxy() { + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + var instance = this; + return setTimeout( handlerProxy, delay || 0 ); + }, + + _hoverable: function( element ) { + this.hoverable = this.hoverable.add( element ); + this._on( element, { + mouseenter: function( event ) { + $( event.currentTarget ).addClass( "ui-state-hover" ); + }, + mouseleave: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-hover" ); + } + }); + }, + + _focusable: function( element ) { + this.focusable = this.focusable.add( element ); + this._on( element, { + focusin: function( event ) { + $( event.currentTarget ).addClass( "ui-state-focus" ); + }, + focusout: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-focus" ); + } + }); + }, + + _trigger: function( type, event, data ) { + var prop, orig, + callback = this.options[ type ]; + + data = data || {}; + event = $.Event( event ); + event.type = ( type === this.widgetEventPrefix ? + type : + this.widgetEventPrefix + type ).toLowerCase(); + // the original event may come from any element + // so we need to reset the target on the new event + event.target = this.element[ 0 ]; + + // copy original event properties over to the new event + orig = event.originalEvent; + if ( orig ) { + for ( prop in orig ) { + if ( !( prop in event ) ) { + event[ prop ] = orig[ prop ]; + } + } + } + + this.element.trigger( event, data ); + return !( $.isFunction( callback ) && + callback.apply( this.element[0], [ event ].concat( data ) ) === false || + event.isDefaultPrevented() ); + } +}; + +$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { + $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { + if ( typeof options === "string" ) { + options = { effect: options }; + } + var hasOptions, + effectName = !options ? + method : + options === true || typeof options === "number" ? + defaultEffect : + options.effect || defaultEffect; + options = options || {}; + if ( typeof options === "number" ) { + options = { duration: options }; + } + hasOptions = !$.isEmptyObject( options ); + options.complete = callback; + if ( options.delay ) { + element.delay( options.delay ); + } + if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) { + element[ method ]( options ); + } else if ( effectName !== method && element[ effectName ] ) { + element[ effectName ]( options.duration, options.easing, callback ); + } else { + element.queue(function( next ) { + $( this )[ method ](); + if ( callback ) { + callback.call( element[ 0 ] ); + } + next(); + }); + } + }; +}); + +// DEPRECATED +if ( $.uiBackCompat !== false ) { + $.Widget.prototype._getCreateOptions = function() { + return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ]; + }; +} + +})( jQuery ); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.validate-1.9.0.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.validate-1.9.0.js new file mode 100644 index 000000000..b7ed45b4a --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery.validate-1.9.0.js @@ -0,0 +1,1188 @@ +/** + * jQuery Validation Plugin 1.9.0 + * + * http://bassistance.de/jquery-plugins/jquery-plugin-validation/ + * http://docs.jquery.com/Plugins/Validation + * + * Copyright (c) 2006 - 2011 Jörn Zaefferer + * + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ + +(function($) { + +$.extend($.fn, { + // http://docs.jquery.com/Plugins/Validation/validate + validate: function( options ) { + + // if nothing is selected, return nothing; can't chain anyway + if (!this.length) { + options && options.debug && window.console && console.warn( "nothing selected, can't validate, returning nothing" ); + return; + } + + // check if a validator for this form was already created + var validator = $.data(this[0], 'validator'); + if ( validator ) { + return validator; + } + + // Add novalidate tag if HTML5. + this.attr('novalidate', 'novalidate'); + + validator = new $.validator( options, this[0] ); + $.data(this[0], 'validator', validator); + + if ( validator.settings.onsubmit ) { + + var inputsAndButtons = this.find("input, button"); + + // allow suppresing validation by adding a cancel class to the submit button + inputsAndButtons.filter(".cancel").click(function () { + validator.cancelSubmit = true; + }); + + // when a submitHandler is used, capture the submitting button + if (validator.settings.submitHandler) { + inputsAndButtons.filter(":submit").click(function () { + validator.submitButton = this; + }); + } + + // validate the form on submit + this.submit( function( event ) { + if ( validator.settings.debug ) + // prevent form submit to be able to see console output + event.preventDefault(); + + function handle() { + if ( validator.settings.submitHandler ) { + if (validator.submitButton) { + // insert a hidden input as a replacement for the missing submit button + var hidden = $("<input type='hidden'/>").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm); + } + validator.settings.submitHandler.call( validator, validator.currentForm ); + if (validator.submitButton) { + // and clean up afterwards; thanks to no-block-scope, hidden can be referenced + hidden.remove(); + } + return false; + } + return true; + } + + // prevent submit for invalid forms or custom submit handlers + if ( validator.cancelSubmit ) { + validator.cancelSubmit = false; + return handle(); + } + if ( validator.form() ) { + if ( validator.pendingRequest ) { + validator.formSubmitted = true; + return false; + } + return handle(); + } else { + validator.focusInvalid(); + return false; + } + }); + } + + return validator; + }, + // http://docs.jquery.com/Plugins/Validation/valid + valid: function() { + if ( $(this[0]).is('form')) { + return this.validate().form(); + } else { + var valid = true; + var validator = $(this[0].form).validate(); + this.each(function() { + valid &= validator.element(this); + }); + return valid; + } + }, + // attributes: space seperated list of attributes to retrieve and remove + removeAttrs: function(attributes) { + var result = {}, + $element = this; + $.each(attributes.split(/\s/), function(index, value) { + result[value] = $element.attr(value); + $element.removeAttr(value); + }); + return result; + }, + // http://docs.jquery.com/Plugins/Validation/rules + rules: function(command, argument) { + var element = this[0]; + + if (command) { + var settings = $.data(element.form, 'validator').settings; + var staticRules = settings.rules; + var existingRules = $.validator.staticRules(element); + switch(command) { + case "add": + $.extend(existingRules, $.validator.normalizeRule(argument)); + staticRules[element.name] = existingRules; + if (argument.messages) + settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages ); + break; + case "remove": + if (!argument) { + delete staticRules[element.name]; + return existingRules; + } + var filtered = {}; + $.each(argument.split(/\s/), function(index, method) { + filtered[method] = existingRules[method]; + delete existingRules[method]; + }); + return filtered; + } + } + + var data = $.validator.normalizeRules( + $.extend( + {}, + $.validator.metadataRules(element), + $.validator.classRules(element), + $.validator.attributeRules(element), + $.validator.staticRules(element) + ), element); + + // make sure required is at front + if (data.required) { + var param = data.required; + delete data.required; + data = $.extend({required: param}, data); + } + + return data; + } +}); + +// Custom selectors +$.extend($.expr[":"], { + // http://docs.jquery.com/Plugins/Validation/blank + blank: function(a) {return !$.trim("" + a.value);}, + // http://docs.jquery.com/Plugins/Validation/filled + filled: function(a) {return !!$.trim("" + a.value);}, + // http://docs.jquery.com/Plugins/Validation/unchecked + unchecked: function(a) {return !a.checked;} +}); + +// constructor for validator +$.validator = function( options, form ) { + this.settings = $.extend( true, {}, $.validator.defaults, options ); + this.currentForm = form; + this.init(); +}; + +$.validator.format = function(source, params) { + if ( arguments.length == 1 ) + return function() { + var args = $.makeArray(arguments); + args.unshift(source); + return $.validator.format.apply( this, args ); + }; + if ( arguments.length > 2 && params.constructor != Array ) { + params = $.makeArray(arguments).slice(1); + } + if ( params.constructor != Array ) { + params = [ params ]; + } + $.each(params, function(i, n) { + source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n); + }); + return source; +}; + +$.extend($.validator, { + + defaults: { + messages: {}, + groups: {}, + rules: {}, + errorClass: "error", + validClass: "valid", + errorElement: "label", + focusInvalid: true, + errorContainer: $( [] ), + errorLabelContainer: $( [] ), + onsubmit: true, + ignore: ":hidden", + ignoreTitle: false, + onfocusin: function(element, event) { + this.lastActive = element; + + // hide error label and remove error class on focus if enabled + if ( this.settings.focusCleanup && !this.blockFocusCleanup ) { + this.settings.unhighlight && this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass ); + this.addWrapper(this.errorsFor(element)).hide(); + } + }, + onfocusout: function(element, event) { + if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) { + this.element(element); + } + }, + onkeyup: function(element, event) { + if ( element.name in this.submitted || element == this.lastElement ) { + this.element(element); + } + }, + onclick: function(element, event) { + // click on selects, radiobuttons and checkboxes + if ( element.name in this.submitted ) + this.element(element); + // or option elements, check parent select in that case + else if (element.parentNode.name in this.submitted) + this.element(element.parentNode); + }, + highlight: function(element, errorClass, validClass) { + if (element.type === 'radio') { + this.findByName(element.name).addClass(errorClass).removeClass(validClass); + } else { + $(element).addClass(errorClass).removeClass(validClass); + } + }, + unhighlight: function(element, errorClass, validClass) { + if (element.type === 'radio') { + this.findByName(element.name).removeClass(errorClass).addClass(validClass); + } else { + $(element).removeClass(errorClass).addClass(validClass); + } + } + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults + setDefaults: function(settings) { + $.extend( $.validator.defaults, settings ); + }, + + messages: { + required: "This field is required.", + remote: "Please fix this field.", + email: "Please enter a valid email address.", + url: "Please enter a valid URL.", + date: "Please enter a valid date.", + dateISO: "Please enter a valid date (ISO).", + number: "Please enter a valid number.", + digits: "Please enter only digits.", + creditcard: "Please enter a valid credit card number.", + equalTo: "Please enter the same value again.", + accept: "Please enter a value with a valid extension.", + maxlength: $.validator.format("Please enter no more than {0} characters."), + minlength: $.validator.format("Please enter at least {0} characters."), + rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."), + range: $.validator.format("Please enter a value between {0} and {1}."), + max: $.validator.format("Please enter a value less than or equal to {0}."), + min: $.validator.format("Please enter a value greater than or equal to {0}.") + }, + + autoCreateRanges: false, + + prototype: { + + init: function() { + this.labelContainer = $(this.settings.errorLabelContainer); + this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm); + this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer ); + this.submitted = {}; + this.valueCache = {}; + this.pendingRequest = 0; + this.pending = {}; + this.invalid = {}; + this.reset(); + + var groups = (this.groups = {}); + $.each(this.settings.groups, function(key, value) { + $.each(value.split(/\s/), function(index, name) { + groups[name] = key; + }); + }); + var rules = this.settings.rules; + $.each(rules, function(key, value) { + rules[key] = $.validator.normalizeRule(value); + }); + + function delegate(event) { + var validator = $.data(this[0].form, "validator"), + eventType = "on" + event.type.replace(/^validate/, ""); + validator.settings[eventType] && validator.settings[eventType].call(validator, this[0], event); + } + $(this.currentForm) + .validateDelegate("[type='text'], [type='password'], [type='file'], select, textarea, " + + "[type='number'], [type='search'] ,[type='tel'], [type='url'], " + + "[type='email'], [type='datetime'], [type='date'], [type='month'], " + + "[type='week'], [type='time'], [type='datetime-local'], " + + "[type='range'], [type='color'] ", + "focusin focusout keyup", delegate) + .validateDelegate("[type='radio'], [type='checkbox'], select, option", "click", delegate); + + if (this.settings.invalidHandler) + $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler); + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/form + form: function() { + this.checkForm(); + $.extend(this.submitted, this.errorMap); + this.invalid = $.extend({}, this.errorMap); + if (!this.valid()) + $(this.currentForm).triggerHandler("invalid-form", [this]); + this.showErrors(); + return this.valid(); + }, + + checkForm: function() { + this.prepareForm(); + for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) { + this.check( elements[i] ); + } + return this.valid(); + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/element + element: function( element ) { + element = this.validationTargetFor( this.clean( element ) ); + this.lastElement = element; + this.prepareElement( element ); + this.currentElements = $(element); + var result = this.check( element ); + if ( result ) { + delete this.invalid[element.name]; + } else { + this.invalid[element.name] = true; + } + if ( !this.numberOfInvalids() ) { + // Hide error containers on last error + this.toHide = this.toHide.add( this.containers ); + } + this.showErrors(); + return result; + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/showErrors + showErrors: function(errors) { + if(errors) { + // add items to error list and map + $.extend( this.errorMap, errors ); + this.errorList = []; + for ( var name in errors ) { + this.errorList.push({ + message: errors[name], + element: this.findByName(name)[0] + }); + } + // remove items from success list + this.successList = $.grep( this.successList, function(element) { + return !(element.name in errors); + }); + } + this.settings.showErrors + ? this.settings.showErrors.call( this, this.errorMap, this.errorList ) + : this.defaultShowErrors(); + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/resetForm + resetForm: function() { + if ( $.fn.resetForm ) + $( this.currentForm ).resetForm(); + this.submitted = {}; + this.lastElement = null; + this.prepareForm(); + this.hideErrors(); + this.elements().removeClass( this.settings.errorClass ); + }, + + numberOfInvalids: function() { + return this.objectLength(this.invalid); + }, + + objectLength: function( obj ) { + var count = 0; + for ( var i in obj ) + count++; + return count; + }, + + hideErrors: function() { + this.addWrapper( this.toHide ).hide(); + }, + + valid: function() { + return this.size() == 0; + }, + + size: function() { + return this.errorList.length; + }, + + focusInvalid: function() { + if( this.settings.focusInvalid ) { + try { + $(this.findLastActive() || this.errorList.length && this.errorList[0].element || []) + .filter(":visible") + .focus() + // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find + .trigger("focusin"); + } catch(e) { + // ignore IE throwing errors when focusing hidden elements + } + } + }, + + findLastActive: function() { + var lastActive = this.lastActive; + return lastActive && $.grep(this.errorList, function(n) { + return n.element.name == lastActive.name; + }).length == 1 && lastActive; + }, + + elements: function() { + var validator = this, + rulesCache = {}; + + // select all valid inputs inside the form (no submit or reset buttons) + return $(this.currentForm) + .find("input, select, textarea") + .not(":submit, :reset, :image, [disabled]") + .not( this.settings.ignore ) + .filter(function() { + !this.name && validator.settings.debug && window.console && console.error( "%o has no name assigned", this); + + // select only the first element for each name, and only those with rules specified + if ( this.name in rulesCache || !validator.objectLength($(this).rules()) ) + return false; + + rulesCache[this.name] = true; + return true; + }); + }, + + clean: function( selector ) { + return $( selector )[0]; + }, + + errors: function() { + return $( this.settings.errorElement + "." + this.settings.errorClass, this.errorContext ); + }, + + reset: function() { + this.successList = []; + this.errorList = []; + this.errorMap = {}; + this.toShow = $([]); + this.toHide = $([]); + this.currentElements = $([]); + }, + + prepareForm: function() { + this.reset(); + this.toHide = this.errors().add( this.containers ); + }, + + prepareElement: function( element ) { + this.reset(); + this.toHide = this.errorsFor(element); + }, + + check: function( element ) { + element = this.validationTargetFor( this.clean( element ) ); + + var rules = $(element).rules(); + var dependencyMismatch = false; + for (var method in rules ) { + var rule = { method: method, parameters: rules[method] }; + try { + var result = $.validator.methods[method].call( this, element.value.replace(/\r/g, ""), element, rule.parameters ); + + // if a method indicates that the field is optional and therefore valid, + // don't mark it as valid when there are no other rules + if ( result == "dependency-mismatch" ) { + dependencyMismatch = true; + continue; + } + dependencyMismatch = false; + + if ( result == "pending" ) { + this.toHide = this.toHide.not( this.errorsFor(element) ); + return; + } + + if( !result ) { + this.formatAndAdd( element, rule ); + return false; + } + } catch(e) { + this.settings.debug && window.console && console.log("exception occured when checking element " + element.id + + ", check the '" + rule.method + "' method", e); + throw e; + } + } + if (dependencyMismatch) + return; + if ( this.objectLength(rules) ) + this.successList.push(element); + return true; + }, + + // return the custom message for the given element and validation method + // specified in the element's "messages" metadata + customMetaMessage: function(element, method) { + if (!$.metadata) + return; + + var meta = this.settings.meta + ? $(element).metadata()[this.settings.meta] + : $(element).metadata(); + + return meta && meta.messages && meta.messages[method]; + }, + + // return the custom message for the given element name and validation method + customMessage: function( name, method ) { + var m = this.settings.messages[name]; + return m && (m.constructor == String + ? m + : m[method]); + }, + + // return the first defined argument, allowing empty strings + findDefined: function() { + for(var i = 0; i < arguments.length; i++) { + if (arguments[i] !== undefined) + return arguments[i]; + } + return undefined; + }, + + defaultMessage: function( element, method) { + return this.findDefined( + this.customMessage( element.name, method ), + this.customMetaMessage( element, method ), + // title is never undefined, so handle empty string as undefined + !this.settings.ignoreTitle && element.title || undefined, + $.validator.messages[method], + "<strong>Warning: No message defined for " + element.name + "</strong>" + ); + }, + + formatAndAdd: function( element, rule ) { + var message = this.defaultMessage( element, rule.method ), + theregex = /\$?\{(\d+)\}/g; + if ( typeof message == "function" ) { + message = message.call(this, rule.parameters, element); + } else if (theregex.test(message)) { + message = jQuery.format(message.replace(theregex, '{$1}'), rule.parameters); + } + this.errorList.push({ + message: message, + element: element + }); + + this.errorMap[element.name] = message; + this.submitted[element.name] = message; + }, + + addWrapper: function(toToggle) { + if ( this.settings.wrapper ) + toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) ); + return toToggle; + }, + + defaultShowErrors: function() { + for ( var i = 0; this.errorList[i]; i++ ) { + var error = this.errorList[i]; + this.settings.highlight && this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass ); + this.showLabel( error.element, error.message ); + } + if( this.errorList.length ) { + this.toShow = this.toShow.add( this.containers ); + } + if (this.settings.success) { + for ( var i = 0; this.successList[i]; i++ ) { + this.showLabel( this.successList[i] ); + } + } + if (this.settings.unhighlight) { + for ( var i = 0, elements = this.validElements(); elements[i]; i++ ) { + this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass ); + } + } + this.toHide = this.toHide.not( this.toShow ); + this.hideErrors(); + this.addWrapper( this.toShow ).show(); + }, + + validElements: function() { + return this.currentElements.not(this.invalidElements()); + }, + + invalidElements: function() { + return $(this.errorList).map(function() { + return this.element; + }); + }, + + showLabel: function(element, message) { + var label = this.errorsFor( element ); + if ( label.length ) { + // refresh error/success class + label.removeClass( this.settings.validClass ).addClass( this.settings.errorClass ); + + // check if we have a generated label, replace the message then + label.attr("generated") && label.html(message); + } else { + // create label + label = $("<" + this.settings.errorElement + "/>") + .attr({"for": this.idOrName(element), generated: true}) + .addClass(this.settings.errorClass) + .html(message || ""); + if ( this.settings.wrapper ) { + // make sure the element is visible, even in IE + // actually showing the wrapped element is handled elsewhere + label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent(); + } + if ( !this.labelContainer.append(label).length ) + this.settings.errorPlacement + ? this.settings.errorPlacement(label, $(element) ) + : label.insertAfter(element); + } + if ( !message && this.settings.success ) { + label.text(""); + typeof this.settings.success == "string" + ? label.addClass( this.settings.success ) + : this.settings.success( label ); + } + this.toShow = this.toShow.add(label); + }, + + errorsFor: function(element) { + var name = this.idOrName(element); + return this.errors().filter(function() { + return $(this).attr('for') == name; + }); + }, + + idOrName: function(element) { + return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name); + }, + + validationTargetFor: function(element) { + // if radio/checkbox, validate first element in group instead + if (this.checkable(element)) { + element = this.findByName( element.name ).not(this.settings.ignore)[0]; + } + return element; + }, + + checkable: function( element ) { + return /radio|checkbox/i.test(element.type); + }, + + findByName: function( name ) { + // select by name and filter by form for performance over form.find("[name=...]") + var form = this.currentForm; + return $(document.getElementsByName(name)).map(function(index, element) { + return element.form == form && element.name == name && element || null; + }); + }, + + getLength: function(value, element) { + switch( element.nodeName.toLowerCase() ) { + case 'select': + return $("option:selected", element).length; + case 'input': + if( this.checkable( element) ) + return this.findByName(element.name).filter(':checked').length; + } + return value.length; + }, + + depend: function(param, element) { + return this.dependTypes[typeof param] + ? this.dependTypes[typeof param](param, element) + : true; + }, + + dependTypes: { + "boolean": function(param, element) { + return param; + }, + "string": function(param, element) { + return !!$(param, element.form).length; + }, + "function": function(param, element) { + return param(element); + } + }, + + optional: function(element) { + return !$.validator.methods.required.call(this, $.trim(element.value), element) && "dependency-mismatch"; + }, + + startRequest: function(element) { + if (!this.pending[element.name]) { + this.pendingRequest++; + this.pending[element.name] = true; + } + }, + + stopRequest: function(element, valid) { + this.pendingRequest--; + // sometimes synchronization fails, make sure pendingRequest is never < 0 + if (this.pendingRequest < 0) + this.pendingRequest = 0; + delete this.pending[element.name]; + if ( valid && this.pendingRequest == 0 && this.formSubmitted && this.form() ) { + $(this.currentForm).submit(); + this.formSubmitted = false; + } else if (!valid && this.pendingRequest == 0 && this.formSubmitted) { + $(this.currentForm).triggerHandler("invalid-form", [this]); + this.formSubmitted = false; + } + }, + + previousValue: function(element) { + return $.data(element, "previousValue") || $.data(element, "previousValue", { + old: null, + valid: true, + message: this.defaultMessage( element, "remote" ) + }); + } + + }, + + classRuleSettings: { + required: {required: true}, + email: {email: true}, + url: {url: true}, + date: {date: true}, + dateISO: {dateISO: true}, + dateDE: {dateDE: true}, + number: {number: true}, + numberDE: {numberDE: true}, + digits: {digits: true}, + creditcard: {creditcard: true} + }, + + addClassRules: function(className, rules) { + className.constructor == String ? + this.classRuleSettings[className] = rules : + $.extend(this.classRuleSettings, className); + }, + + classRules: function(element) { + var rules = {}; + var classes = $(element).attr('class'); + classes && $.each(classes.split(' '), function() { + if (this in $.validator.classRuleSettings) { + $.extend(rules, $.validator.classRuleSettings[this]); + } + }); + return rules; + }, + + attributeRules: function(element) { + var rules = {}; + var $element = $(element); + + for (var method in $.validator.methods) { + var value; + // If .prop exists (jQuery >= 1.6), use it to get true/false for required + if (method === 'required' && typeof $.fn.prop === 'function') { + value = $element.prop(method); + } else { + value = $element.attr(method); + } + if (value) { + rules[method] = value; + } else if ($element[0].getAttribute("type") === method) { + rules[method] = true; + } + } + + // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs + if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) { + delete rules.maxlength; + } + + return rules; + }, + + metadataRules: function(element) { + if (!$.metadata) return {}; + + var meta = $.data(element.form, 'validator').settings.meta; + return meta ? + $(element).metadata()[meta] : + $(element).metadata(); + }, + + staticRules: function(element) { + var rules = {}; + var validator = $.data(element.form, 'validator'); + if (validator.settings.rules) { + rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {}; + } + return rules; + }, + + normalizeRules: function(rules, element) { + // handle dependency check + $.each(rules, function(prop, val) { + // ignore rule when param is explicitly false, eg. required:false + if (val === false) { + delete rules[prop]; + return; + } + if (val.param || val.depends) { + var keepRule = true; + switch (typeof val.depends) { + case "string": + keepRule = !!$(val.depends, element.form).length; + break; + case "function": + keepRule = val.depends.call(element, element); + break; + } + if (keepRule) { + rules[prop] = val.param !== undefined ? val.param : true; + } else { + delete rules[prop]; + } + } + }); + + // evaluate parameters + $.each(rules, function(rule, parameter) { + rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter; + }); + + // clean number parameters + $.each(['minlength', 'maxlength', 'min', 'max'], function() { + if (rules[this]) { + rules[this] = Number(rules[this]); + } + }); + $.each(['rangelength', 'range'], function() { + if (rules[this]) { + rules[this] = [Number(rules[this][0]), Number(rules[this][1])]; + } + }); + + if ($.validator.autoCreateRanges) { + // auto-create ranges + if (rules.min && rules.max) { + rules.range = [rules.min, rules.max]; + delete rules.min; + delete rules.max; + } + if (rules.minlength && rules.maxlength) { + rules.rangelength = [rules.minlength, rules.maxlength]; + delete rules.minlength; + delete rules.maxlength; + } + } + + // To support custom messages in metadata ignore rule methods titled "messages" + if (rules.messages) { + delete rules.messages; + } + + return rules; + }, + + // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true} + normalizeRule: function(data) { + if( typeof data == "string" ) { + var transformed = {}; + $.each(data.split(/\s/), function() { + transformed[this] = true; + }); + data = transformed; + } + return data; + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/addMethod + addMethod: function(name, method, message) { + $.validator.methods[name] = method; + $.validator.messages[name] = message != undefined ? message : $.validator.messages[name]; + if (method.length < 3) { + $.validator.addClassRules(name, $.validator.normalizeRule(name)); + } + }, + + methods: { + + // http://docs.jquery.com/Plugins/Validation/Methods/required + required: function(value, element, param) { + // check if dependency is met + if ( !this.depend(param, element) ) + return "dependency-mismatch"; + switch( element.nodeName.toLowerCase() ) { + case 'select': + // could be an array for select-multiple or a string, both are fine this way + var val = $(element).val(); + return val && val.length > 0; + case 'input': + if ( this.checkable(element) ) + return this.getLength(value, element) > 0; + default: + return $.trim(value).length > 0; + } + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/remote + remote: function(value, element, param) { + if ( this.optional(element) ) + return "dependency-mismatch"; + + var previous = this.previousValue(element); + if (!this.settings.messages[element.name] ) + this.settings.messages[element.name] = {}; + previous.originalMessage = this.settings.messages[element.name].remote; + this.settings.messages[element.name].remote = previous.message; + + param = typeof param == "string" && {url:param} || param; + + if ( this.pending[element.name] ) { + return "pending"; + } + if ( previous.old === value ) { + return previous.valid; + } + + previous.old = value; + var validator = this; + this.startRequest(element); + var data = {}; + data[element.name] = value; + $.ajax($.extend(true, { + url: param, + mode: "abort", + port: "validate" + element.name, + dataType: "json", + data: data, + success: function(response) { + validator.settings.messages[element.name].remote = previous.originalMessage; + var valid = response === true; + if ( valid ) { + var submitted = validator.formSubmitted; + validator.prepareElement(element); + validator.formSubmitted = submitted; + validator.successList.push(element); + validator.showErrors(); + } else { + var errors = {}; + var message = response || validator.defaultMessage( element, "remote" ); + errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message; + validator.showErrors(errors); + } + previous.valid = valid; + validator.stopRequest(element, valid); + } + }, param)); + return "pending"; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/minlength + minlength: function(value, element, param) { + return this.optional(element) || this.getLength($.trim(value), element) >= param; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/maxlength + maxlength: function(value, element, param) { + return this.optional(element) || this.getLength($.trim(value), element) <= param; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/rangelength + rangelength: function(value, element, param) { + var length = this.getLength($.trim(value), element); + return this.optional(element) || ( length >= param[0] && length <= param[1] ); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/min + min: function( value, element, param ) { + return this.optional(element) || value >= param; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/max + max: function( value, element, param ) { + return this.optional(element) || value <= param; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/range + range: function( value, element, param ) { + return this.optional(element) || ( value >= param[0] && value <= param[1] ); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/email + email: function(value, element) { + // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/ + return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/url + url: function(value, element) { + // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/ + return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/date + date: function(value, element) { + return this.optional(element) || !/Invalid|NaN/.test(new Date(value)); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/dateISO + dateISO: function(value, element) { + return this.optional(element) || /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/number + number: function(value, element) { + return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/digits + digits: function(value, element) { + return this.optional(element) || /^\d+$/.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/creditcard + // based on http://en.wikipedia.org/wiki/Luhn + creditcard: function(value, element) { + if ( this.optional(element) ) + return "dependency-mismatch"; + // accept only spaces, digits and dashes + if (/[^0-9 -]+/.test(value)) + return false; + var nCheck = 0, + nDigit = 0, + bEven = false; + + value = value.replace(/\D/g, ""); + + for (var n = value.length - 1; n >= 0; n--) { + var cDigit = value.charAt(n); + var nDigit = parseInt(cDigit, 10); + if (bEven) { + if ((nDigit *= 2) > 9) + nDigit -= 9; + } + nCheck += nDigit; + bEven = !bEven; + } + + return (nCheck % 10) == 0; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/accept + accept: function(value, element, param) { + param = typeof param == "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif"; + return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i")); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/equalTo + equalTo: function(value, element, param) { + // bind to the blur event of the target in order to revalidate whenever the target field is updated + // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead + var target = $(param).unbind(".validate-equalTo").bind("blur.validate-equalTo", function() { + $(element).valid(); + }); + return value == target.val(); + } + + } + +}); + +// deprecated, use $.validator.format instead +$.format = $.validator.format; + +})(jQuery); + +// ajax mode: abort +// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); +// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() +;(function($) { + var pendingRequests = {}; + // Use a prefilter if available (1.5+) + if ( $.ajaxPrefilter ) { + $.ajaxPrefilter(function(settings, _, xhr) { + var port = settings.port; + if (settings.mode == "abort") { + if ( pendingRequests[port] ) { + pendingRequests[port].abort(); + } + pendingRequests[port] = xhr; + } + }); + } else { + // Proxy ajax + var ajax = $.ajax; + $.ajax = function(settings) { + var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode, + port = ( "port" in settings ? settings : $.ajaxSettings ).port; + if (mode == "abort") { + if ( pendingRequests[port] ) { + pendingRequests[port].abort(); + } + return (pendingRequests[port] = ajax.apply(this, arguments)); + } + return ajax.apply(this, arguments); + }; + } +})(jQuery); + +// provides cross-browser focusin and focusout events +// IE has native support, in other browsers, use event caputuring (neither bubbles) + +// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation +// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target +;(function($) { + // only implement if not provided by jQuery core (since 1.4) + // TODO verify if jQuery 1.4's implementation is compatible with older jQuery special-event APIs + if (!jQuery.event.special.focusin && !jQuery.event.special.focusout && document.addEventListener) { + $.each({ + focus: 'focusin', + blur: 'focusout' + }, function( original, fix ){ + $.event.special[fix] = { + setup:function() { + this.addEventListener( original, handler, true ); + }, + teardown:function() { + this.removeEventListener( original, handler, true ); + }, + handler: function(e) { + arguments[0] = $.event.fix(e); + arguments[0].type = fix; + return $.event.handle.apply(this, arguments); + } + }; + function handler(e) { + e = $.event.fix(e); + e.type = fix; + return $.event.handle.call(this, e); + } + }); + }; + $.extend($.fn, { + validateDelegate: function(delegate, type, handler) { + return this.bind(type, function(event) { + var target = $(event.target); + if (target.is(delegate)) { + return handler.apply(target, arguments); + } + }); + } + }); +})(jQuery); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jqueryFileTree-1.0.1.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jqueryFileTree-1.0.1.js new file mode 100755 index 000000000..289b8e329 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jqueryFileTree-1.0.1.js @@ -0,0 +1,102 @@ +// jQuery File Tree Plugin +// +// Version 1.01 +// +// Cory S.N. LaViska +// A Beautiful Site (http://abeautifulsite.net/) +// 24 March 2008 +// +// Visit http://abeautifulsite.net/notebook.php?article=58 for more information +// +// Usage: $('.fileTreeDemo').fileTree( options, callback ) +// +// Options: root - root folder to display; default = / +// script - location of the serverside AJAX file to use; default = jqueryFileTree.php +// folderEvent - event to trigger expand/collapse; default = click +// expandSpeed - default = 500 (ms); use -1 for no animation +// collapseSpeed - default = 500 (ms); use -1 for no animation +// expandEasing - easing function to use on expand (optional) +// collapseEasing - easing function to use on collapse (optional) +// multiFolder - whether or not to limit the browser to one subfolder at a time +// loadMessage - Message to display while initial tree loads (can be HTML) +// +// History: +// +// 1.01 - updated to work with foreign characters in directory/file names (12 April 2008) +// 1.00 - released (24 March 2008) +// +// TERMS OF USE +// +// This plugin is dual-licensed under the GNU General Public License and the MIT License and +// is copyright 2008 A Beautiful Site, LLC. +// +if(jQuery) (function($){ + + $.extend($.fn, { + fileTree: function(o, h) { + // Defaults + if( !o ) var o = {}; + if( o.root == undefined ) o.root = '/'; + if( o.script == undefined ) o.script = 'jqueryFileTree.php'; + if( o.folderEvent == undefined ) o.folderEvent = 'click'; + if( o.expandSpeed == undefined ) o.expandSpeed= 500; + if( o.collapseSpeed == undefined ) o.collapseSpeed= 500; + if( o.expandEasing == undefined ) o.expandEasing = null; + if( o.collapseEasing == undefined ) o.collapseEasing = null; + if( o.multiFolder == undefined ) o.multiFolder = true; + if( o.loadMessage == undefined ) o.loadMessage = 'Loading...'; + + $(this).each( function() { + + function showTree(c, t) { + $(c).addClass('wait'); + $(".jqueryFileTree.start").remove(); + $.get(o.script, { p: t }, function(data) { + $(c).find('.start').html(''); + var artifactContentEntries=mapArtifactContentEntries(data); + $(artifactContentEntries ).each(function(idx, elem){ + elem.text=elem.path.substr( t.length, elem.path.length); + }); + var htmlContent = $("#artifact_content_tree_partial" ).tmpl( + {artifactContentEntries:artifactContentEntries} + ); + $(c).removeClass('wait').append(htmlContent); + if( o.root == t ) $(c).find('UL:hidden').show(); else $(c).find('UL:hidden').slideDown({ duration: o.expandSpeed, easing: o.expandEasing }); + bindTree(c); + }); + } + + function bindTree(t) { + $(t).find('LI A').bind(o.folderEvent, function() { + if( $(this).parent().hasClass('directory') ) { + if( $(this).parent().hasClass('collapsed') ) { + // Expand + if( !o.multiFolder ) { + $(this).parent().parent().find('UL').slideUp({ duration: o.collapseSpeed, easing: o.collapseEasing }); + $(this).parent().parent().find('LI.directory').removeClass('expanded').addClass('collapsed'); + } + $(this).parent().find('UL').remove(); // cleanup + showTree( $(this).parent(), escape($(this).attr('rel')) );//.match( /.*\// ) + $(this).parent().removeClass('collapsed').addClass('expanded'); + } else { + // Collapse + $(this).parent().find('UL').slideUp({ duration: o.collapseSpeed, easing: o.collapseEasing }); + $(this).parent().removeClass('expanded').addClass('collapsed'); + } + } else { + h($(this).attr('rel')); + } + return false; + }); + // Prevent A from triggering the # on non-click events + if( o.folderEvent.toLowerCase != 'click' ) $(t).find('LI A').bind('click', function() { return false; }); + } + // Loading message + $(this).html('<ul class="jqueryFileTree start"><li class="wait">' + o.loadMessage + '<li></ul>'); + // Get the initial file list + showTree( $(this), escape(o.root) ); + }); + } + }); + +})(jQuery);
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/knockout-2.2.0.debug.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/knockout-2.2.0.debug.js new file mode 100644 index 000000000..61c2a0e22 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/knockout-2.2.0.debug.js @@ -0,0 +1,3577 @@ +// Knockout JavaScript library v2.2.0 +// (c) Steven Sanderson - http://knockoutjs.com/ +// License: MIT (http://www.opensource.org/licenses/mit-license.php) + +(function(){ +var DEBUG=true; +(function(window,document,navigator,jQuery,undefined){ +!function(factory) { + // Support three module loading scenarios + if (typeof require === 'function' && typeof exports === 'object' && typeof module === 'object') { + // [1] CommonJS/Node.js + var target = module['exports'] || exports; // module.exports is for Node.js + factory(target); + } else if (typeof define === 'function' && define['amd']) { + // [2] AMD anonymous module + define(['exports'], factory); + } else { + // [3] No module loader (plain <script> tag) - put directly in global namespace + factory(window['ko'] = {}); + } +}(function(koExports){ +// Internally, all KO objects are attached to koExports (even the non-exported ones whose names will be minified by the closure compiler). +// In the future, the following "ko" variable may be made distinct from "koExports" so that private objects are not externally reachable. +var ko = typeof koExports !== 'undefined' ? koExports : {}; +// Google Closure Compiler helpers (used only to make the minified file smaller) +ko.exportSymbol = function(koPath, object) { + var tokens = koPath.split("."); + + // In the future, "ko" may become distinct from "koExports" (so that non-exported objects are not reachable) + // At that point, "target" would be set to: (typeof koExports !== "undefined" ? koExports : ko) + var target = ko; + + for (var i = 0; i < tokens.length - 1; i++) + target = target[tokens[i]]; + target[tokens[tokens.length - 1]] = object; +}; +ko.exportProperty = function(owner, publicName, object) { + owner[publicName] = object; +}; +ko.version = "2.2.0"; + +ko.exportSymbol('version', ko.version); +ko.utils = new (function () { + var stringTrimRegex = /^(\s|\u00A0)+|(\s|\u00A0)+$/g; + + // Represent the known event types in a compact way, then at runtime transform it into a hash with event name as key (for fast lookup) + var knownEvents = {}, knownEventTypesByEventName = {}; + var keyEventTypeName = /Firefox\/2/i.test(navigator.userAgent) ? 'KeyboardEvent' : 'UIEvents'; + knownEvents[keyEventTypeName] = ['keyup', 'keydown', 'keypress']; + knownEvents['MouseEvents'] = ['click', 'dblclick', 'mousedown', 'mouseup', 'mousemove', 'mouseover', 'mouseout', 'mouseenter', 'mouseleave']; + for (var eventType in knownEvents) { + var knownEventsForType = knownEvents[eventType]; + if (knownEventsForType.length) { + for (var i = 0, j = knownEventsForType.length; i < j; i++) + knownEventTypesByEventName[knownEventsForType[i]] = eventType; + } + } + var eventsThatMustBeRegisteredUsingAttachEvent = { 'propertychange': true }; // Workaround for an IE9 issue - https://github.com/SteveSanderson/knockout/issues/406 + + // Detect IE versions for bug workarounds (uses IE conditionals, not UA string, for robustness) + // Note that, since IE 10 does not support conditional comments, the following logic only detects IE < 10. + // Currently this is by design, since IE 10+ behaves correctly when treated as a standard browser. + // If there is a future need to detect specific versions of IE10+, we will amend this. + var ieVersion = (function() { + var version = 3, div = document.createElement('div'), iElems = div.getElementsByTagName('i'); + + // Keep constructing conditional HTML blocks until we hit one that resolves to an empty fragment + while ( + div.innerHTML = '<!--[if gt IE ' + (++version) + ']><i></i><![endif]-->', + iElems[0] + ); + return version > 4 ? version : undefined; + }()); + var isIe6 = ieVersion === 6, + isIe7 = ieVersion === 7; + + function isClickOnCheckableElement(element, eventType) { + if ((ko.utils.tagNameLower(element) !== "input") || !element.type) return false; + if (eventType.toLowerCase() != "click") return false; + var inputType = element.type; + return (inputType == "checkbox") || (inputType == "radio"); + } + + return { + fieldsIncludedWithJsonPost: ['authenticity_token', /^__RequestVerificationToken(_.*)?$/], + + arrayForEach: function (array, action) { + for (var i = 0, j = array.length; i < j; i++) + action(array[i]); + }, + + arrayIndexOf: function (array, item) { + if (typeof Array.prototype.indexOf == "function") + return Array.prototype.indexOf.call(array, item); + for (var i = 0, j = array.length; i < j; i++) + if (array[i] === item) + return i; + return -1; + }, + + arrayFirst: function (array, predicate, predicateOwner) { + for (var i = 0, j = array.length; i < j; i++) + if (predicate.call(predicateOwner, array[i])) + return array[i]; + return null; + }, + + arrayRemoveItem: function (array, itemToRemove) { + var index = ko.utils.arrayIndexOf(array, itemToRemove); + if (index >= 0) + array.splice(index, 1); + }, + + arrayGetDistinctValues: function (array) { + array = array || []; + var result = []; + for (var i = 0, j = array.length; i < j; i++) { + if (ko.utils.arrayIndexOf(result, array[i]) < 0) + result.push(array[i]); + } + return result; + }, + + arrayMap: function (array, mapping) { + array = array || []; + var result = []; + for (var i = 0, j = array.length; i < j; i++) + result.push(mapping(array[i])); + return result; + }, + + arrayFilter: function (array, predicate) { + array = array || []; + var result = []; + for (var i = 0, j = array.length; i < j; i++) + if (predicate(array[i])) + result.push(array[i]); + return result; + }, + + arrayPushAll: function (array, valuesToPush) { + if (valuesToPush instanceof Array) + array.push.apply(array, valuesToPush); + else + for (var i = 0, j = valuesToPush.length; i < j; i++) + array.push(valuesToPush[i]); + return array; + }, + + extend: function (target, source) { + if (source) { + for(var prop in source) { + if(source.hasOwnProperty(prop)) { + target[prop] = source[prop]; + } + } + } + return target; + }, + + emptyDomNode: function (domNode) { + while (domNode.firstChild) { + ko.removeNode(domNode.firstChild); + } + }, + + moveCleanedNodesToContainerElement: function(nodes) { + // Ensure it's a real array, as we're about to reparent the nodes and + // we don't want the underlying collection to change while we're doing that. + var nodesArray = ko.utils.makeArray(nodes); + + var container = document.createElement('div'); + for (var i = 0, j = nodesArray.length; i < j; i++) { + container.appendChild(ko.cleanNode(nodesArray[i])); + } + return container; + }, + + cloneNodes: function (nodesArray, shouldCleanNodes) { + for (var i = 0, j = nodesArray.length, newNodesArray = []; i < j; i++) { + var clonedNode = nodesArray[i].cloneNode(true); + newNodesArray.push(shouldCleanNodes ? ko.cleanNode(clonedNode) : clonedNode); + } + return newNodesArray; + }, + + setDomNodeChildren: function (domNode, childNodes) { + ko.utils.emptyDomNode(domNode); + if (childNodes) { + for (var i = 0, j = childNodes.length; i < j; i++) + domNode.appendChild(childNodes[i]); + } + }, + + replaceDomNodes: function (nodeToReplaceOrNodeArray, newNodesArray) { + var nodesToReplaceArray = nodeToReplaceOrNodeArray.nodeType ? [nodeToReplaceOrNodeArray] : nodeToReplaceOrNodeArray; + if (nodesToReplaceArray.length > 0) { + var insertionPoint = nodesToReplaceArray[0]; + var parent = insertionPoint.parentNode; + for (var i = 0, j = newNodesArray.length; i < j; i++) + parent.insertBefore(newNodesArray[i], insertionPoint); + for (var i = 0, j = nodesToReplaceArray.length; i < j; i++) { + ko.removeNode(nodesToReplaceArray[i]); + } + } + }, + + setOptionNodeSelectionState: function (optionNode, isSelected) { + // IE6 sometimes throws "unknown error" if you try to write to .selected directly, whereas Firefox struggles with setAttribute. Pick one based on browser. + if (ieVersion < 7) + optionNode.setAttribute("selected", isSelected); + else + optionNode.selected = isSelected; + }, + + stringTrim: function (string) { + return (string || "").replace(stringTrimRegex, ""); + }, + + stringTokenize: function (string, delimiter) { + var result = []; + var tokens = (string || "").split(delimiter); + for (var i = 0, j = tokens.length; i < j; i++) { + var trimmed = ko.utils.stringTrim(tokens[i]); + if (trimmed !== "") + result.push(trimmed); + } + return result; + }, + + stringStartsWith: function (string, startsWith) { + string = string || ""; + if (startsWith.length > string.length) + return false; + return string.substring(0, startsWith.length) === startsWith; + }, + + domNodeIsContainedBy: function (node, containedByNode) { + if (containedByNode.compareDocumentPosition) + return (containedByNode.compareDocumentPosition(node) & 16) == 16; + while (node != null) { + if (node == containedByNode) + return true; + node = node.parentNode; + } + return false; + }, + + domNodeIsAttachedToDocument: function (node) { + return ko.utils.domNodeIsContainedBy(node, node.ownerDocument); + }, + + tagNameLower: function(element) { + // For HTML elements, tagName will always be upper case; for XHTML elements, it'll be lower case. + // Possible future optimization: If we know it's an element from an XHTML document (not HTML), + // we don't need to do the .toLowerCase() as it will always be lower case anyway. + return element && element.tagName && element.tagName.toLowerCase(); + }, + + registerEventHandler: function (element, eventType, handler) { + var mustUseAttachEvent = ieVersion && eventsThatMustBeRegisteredUsingAttachEvent[eventType]; + if (!mustUseAttachEvent && typeof jQuery != "undefined") { + if (isClickOnCheckableElement(element, eventType)) { + // For click events on checkboxes, jQuery interferes with the event handling in an awkward way: + // it toggles the element checked state *after* the click event handlers run, whereas native + // click events toggle the checked state *before* the event handler. + // Fix this by intecepting the handler and applying the correct checkedness before it runs. + var originalHandler = handler; + handler = function(event, eventData) { + var jQuerySuppliedCheckedState = this.checked; + if (eventData) + this.checked = eventData.checkedStateBeforeEvent !== true; + originalHandler.call(this, event); + this.checked = jQuerySuppliedCheckedState; // Restore the state jQuery applied + }; + } + jQuery(element)['bind'](eventType, handler); + } else if (!mustUseAttachEvent && typeof element.addEventListener == "function") + element.addEventListener(eventType, handler, false); + else if (typeof element.attachEvent != "undefined") + element.attachEvent("on" + eventType, function (event) { + handler.call(element, event); + }); + else + throw new Error("Browser doesn't support addEventListener or attachEvent"); + }, + + triggerEvent: function (element, eventType) { + if (!(element && element.nodeType)) + throw new Error("element must be a DOM node when calling triggerEvent"); + + if (typeof jQuery != "undefined") { + var eventData = []; + if (isClickOnCheckableElement(element, eventType)) { + // Work around the jQuery "click events on checkboxes" issue described above by storing the original checked state before triggering the handler + eventData.push({ checkedStateBeforeEvent: element.checked }); + } + jQuery(element)['trigger'](eventType, eventData); + } else if (typeof document.createEvent == "function") { + if (typeof element.dispatchEvent == "function") { + var eventCategory = knownEventTypesByEventName[eventType] || "HTMLEvents"; + var event = document.createEvent(eventCategory); + event.initEvent(eventType, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, element); + element.dispatchEvent(event); + } + else + throw new Error("The supplied element doesn't support dispatchEvent"); + } else if (typeof element.fireEvent != "undefined") { + // Unlike other browsers, IE doesn't change the checked state of checkboxes/radiobuttons when you trigger their "click" event + // so to make it consistent, we'll do it manually here + if (isClickOnCheckableElement(element, eventType)) + element.checked = element.checked !== true; + element.fireEvent("on" + eventType); + } + else + throw new Error("Browser doesn't support triggering events"); + }, + + unwrapObservable: function (value) { + return ko.isObservable(value) ? value() : value; + }, + + peekObservable: function (value) { + return ko.isObservable(value) ? value.peek() : value; + }, + + toggleDomNodeCssClass: function (node, classNames, shouldHaveClass) { + if (classNames) { + var cssClassNameRegex = /[\w-]+/g, + currentClassNames = node.className.match(cssClassNameRegex) || []; + ko.utils.arrayForEach(classNames.match(cssClassNameRegex), function(className) { + var indexOfClass = ko.utils.arrayIndexOf(currentClassNames, className); + if (indexOfClass >= 0) { + if (!shouldHaveClass) + currentClassNames.splice(indexOfClass, 1); + } else { + if (shouldHaveClass) + currentClassNames.push(className); + } + }); + node.className = currentClassNames.join(" "); + } + }, + + setTextContent: function(element, textContent) { + var value = ko.utils.unwrapObservable(textContent); + if ((value === null) || (value === undefined)) + value = ""; + + if (element.nodeType === 3) { + element.data = value; + } else { + // We need there to be exactly one child: a text node. + // If there are no children, more than one, or if it's not a text node, + // we'll clear everything and create a single text node. + var innerTextNode = ko.virtualElements.firstChild(element); + if (!innerTextNode || innerTextNode.nodeType != 3 || ko.virtualElements.nextSibling(innerTextNode)) { + ko.virtualElements.setDomNodeChildren(element, [document.createTextNode(value)]); + } else { + innerTextNode.data = value; + } + + ko.utils.forceRefresh(element); + } + }, + + setElementName: function(element, name) { + element.name = name; + + // Workaround IE 6/7 issue + // - https://github.com/SteveSanderson/knockout/issues/197 + // - http://www.matts411.com/post/setting_the_name_attribute_in_ie_dom/ + if (ieVersion <= 7) { + try { + element.mergeAttributes(document.createElement("<input name='" + element.name + "'/>"), false); + } + catch(e) {} // For IE9 with doc mode "IE9 Standards" and browser mode "IE9 Compatibility View" + } + }, + + forceRefresh: function(node) { + // Workaround for an IE9 rendering bug - https://github.com/SteveSanderson/knockout/issues/209 + if (ieVersion >= 9) { + // For text nodes and comment nodes (most likely virtual elements), we will have to refresh the container + var elem = node.nodeType == 1 ? node : node.parentNode; + if (elem.style) + elem.style.zoom = elem.style.zoom; + } + }, + + ensureSelectElementIsRenderedCorrectly: function(selectElement) { + // Workaround for IE9 rendering bug - it doesn't reliably display all the text in dynamically-added select boxes unless you force it to re-render by updating the width. + // (See https://github.com/SteveSanderson/knockout/issues/312, http://stackoverflow.com/questions/5908494/select-only-shows-first-char-of-selected-option) + if (ieVersion >= 9) { + var originalWidth = selectElement.style.width; + selectElement.style.width = 0; + selectElement.style.width = originalWidth; + } + }, + + range: function (min, max) { + min = ko.utils.unwrapObservable(min); + max = ko.utils.unwrapObservable(max); + var result = []; + for (var i = min; i <= max; i++) + result.push(i); + return result; + }, + + makeArray: function(arrayLikeObject) { + var result = []; + for (var i = 0, j = arrayLikeObject.length; i < j; i++) { + result.push(arrayLikeObject[i]); + }; + return result; + }, + + isIe6 : isIe6, + isIe7 : isIe7, + ieVersion : ieVersion, + + getFormFields: function(form, fieldName) { + var fields = ko.utils.makeArray(form.getElementsByTagName("input")).concat(ko.utils.makeArray(form.getElementsByTagName("textarea"))); + var isMatchingField = (typeof fieldName == 'string') + ? function(field) { return field.name === fieldName } + : function(field) { return fieldName.test(field.name) }; // Treat fieldName as regex or object containing predicate + var matches = []; + for (var i = fields.length - 1; i >= 0; i--) { + if (isMatchingField(fields[i])) + matches.push(fields[i]); + }; + return matches; + }, + + parseJson: function (jsonString) { + if (typeof jsonString == "string") { + jsonString = ko.utils.stringTrim(jsonString); + if (jsonString) { + if (window.JSON && window.JSON.parse) // Use native parsing where available + return window.JSON.parse(jsonString); + return (new Function("return " + jsonString))(); // Fallback on less safe parsing for older browsers + } + } + return null; + }, + + stringifyJson: function (data, replacer, space) { // replacer and space are optional + if ((typeof JSON == "undefined") || (typeof JSON.stringify == "undefined")) + throw new Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js"); + return JSON.stringify(ko.utils.unwrapObservable(data), replacer, space); + }, + + postJson: function (urlOrForm, data, options) { + options = options || {}; + var params = options['params'] || {}; + var includeFields = options['includeFields'] || this.fieldsIncludedWithJsonPost; + var url = urlOrForm; + + // If we were given a form, use its 'action' URL and pick out any requested field values + if((typeof urlOrForm == 'object') && (ko.utils.tagNameLower(urlOrForm) === "form")) { + var originalForm = urlOrForm; + url = originalForm.action; + for (var i = includeFields.length - 1; i >= 0; i--) { + var fields = ko.utils.getFormFields(originalForm, includeFields[i]); + for (var j = fields.length - 1; j >= 0; j--) + params[fields[j].name] = fields[j].value; + } + } + + data = ko.utils.unwrapObservable(data); + var form = document.createElement("form"); + form.style.display = "none"; + form.action = url; + form.method = "post"; + for (var key in data) { + var input = document.createElement("input"); + input.name = key; + input.value = ko.utils.stringifyJson(ko.utils.unwrapObservable(data[key])); + form.appendChild(input); + } + for (var key in params) { + var input = document.createElement("input"); + input.name = key; + input.value = params[key]; + form.appendChild(input); + } + document.body.appendChild(form); + options['submitter'] ? options['submitter'](form) : form.submit(); + setTimeout(function () { form.parentNode.removeChild(form); }, 0); + } + } +})(); + +ko.exportSymbol('utils', ko.utils); +ko.exportSymbol('utils.arrayForEach', ko.utils.arrayForEach); +ko.exportSymbol('utils.arrayFirst', ko.utils.arrayFirst); +ko.exportSymbol('utils.arrayFilter', ko.utils.arrayFilter); +ko.exportSymbol('utils.arrayGetDistinctValues', ko.utils.arrayGetDistinctValues); +ko.exportSymbol('utils.arrayIndexOf', ko.utils.arrayIndexOf); +ko.exportSymbol('utils.arrayMap', ko.utils.arrayMap); +ko.exportSymbol('utils.arrayPushAll', ko.utils.arrayPushAll); +ko.exportSymbol('utils.arrayRemoveItem', ko.utils.arrayRemoveItem); +ko.exportSymbol('utils.extend', ko.utils.extend); +ko.exportSymbol('utils.fieldsIncludedWithJsonPost', ko.utils.fieldsIncludedWithJsonPost); +ko.exportSymbol('utils.getFormFields', ko.utils.getFormFields); +ko.exportSymbol('utils.peekObservable', ko.utils.peekObservable); +ko.exportSymbol('utils.postJson', ko.utils.postJson); +ko.exportSymbol('utils.parseJson', ko.utils.parseJson); +ko.exportSymbol('utils.registerEventHandler', ko.utils.registerEventHandler); +ko.exportSymbol('utils.stringifyJson', ko.utils.stringifyJson); +ko.exportSymbol('utils.range', ko.utils.range); +ko.exportSymbol('utils.toggleDomNodeCssClass', ko.utils.toggleDomNodeCssClass); +ko.exportSymbol('utils.triggerEvent', ko.utils.triggerEvent); +ko.exportSymbol('utils.unwrapObservable', ko.utils.unwrapObservable); + +if (!Function.prototype['bind']) { + // Function.prototype.bind is a standard part of ECMAScript 5th Edition (December 2009, http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf) + // In case the browser doesn't implement it natively, provide a JavaScript implementation. This implementation is based on the one in prototype.js + Function.prototype['bind'] = function (object) { + var originalFunction = this, args = Array.prototype.slice.call(arguments), object = args.shift(); + return function () { + return originalFunction.apply(object, args.concat(Array.prototype.slice.call(arguments))); + }; + }; +} + +ko.utils.domData = new (function () { + var uniqueId = 0; + var dataStoreKeyExpandoPropertyName = "__ko__" + (new Date).getTime(); + var dataStore = {}; + return { + get: function (node, key) { + var allDataForNode = ko.utils.domData.getAll(node, false); + return allDataForNode === undefined ? undefined : allDataForNode[key]; + }, + set: function (node, key, value) { + if (value === undefined) { + // Make sure we don't actually create a new domData key if we are actually deleting a value + if (ko.utils.domData.getAll(node, false) === undefined) + return; + } + var allDataForNode = ko.utils.domData.getAll(node, true); + allDataForNode[key] = value; + }, + getAll: function (node, createIfNotFound) { + var dataStoreKey = node[dataStoreKeyExpandoPropertyName]; + var hasExistingDataStore = dataStoreKey && (dataStoreKey !== "null") && dataStore[dataStoreKey]; + if (!hasExistingDataStore) { + if (!createIfNotFound) + return undefined; + dataStoreKey = node[dataStoreKeyExpandoPropertyName] = "ko" + uniqueId++; + dataStore[dataStoreKey] = {}; + } + return dataStore[dataStoreKey]; + }, + clear: function (node) { + var dataStoreKey = node[dataStoreKeyExpandoPropertyName]; + if (dataStoreKey) { + delete dataStore[dataStoreKey]; + node[dataStoreKeyExpandoPropertyName] = null; + return true; // Exposing "did clean" flag purely so specs can infer whether things have been cleaned up as intended + } + return false; + } + } +})(); + +ko.exportSymbol('utils.domData', ko.utils.domData); +ko.exportSymbol('utils.domData.clear', ko.utils.domData.clear); // Exporting only so specs can clear up after themselves fully + +ko.utils.domNodeDisposal = new (function () { + var domDataKey = "__ko_domNodeDisposal__" + (new Date).getTime(); + var cleanableNodeTypes = { 1: true, 8: true, 9: true }; // Element, Comment, Document + var cleanableNodeTypesWithDescendants = { 1: true, 9: true }; // Element, Document + + function getDisposeCallbacksCollection(node, createIfNotFound) { + var allDisposeCallbacks = ko.utils.domData.get(node, domDataKey); + if ((allDisposeCallbacks === undefined) && createIfNotFound) { + allDisposeCallbacks = []; + ko.utils.domData.set(node, domDataKey, allDisposeCallbacks); + } + return allDisposeCallbacks; + } + function destroyCallbacksCollection(node) { + ko.utils.domData.set(node, domDataKey, undefined); + } + + function cleanSingleNode(node) { + // Run all the dispose callbacks + var callbacks = getDisposeCallbacksCollection(node, false); + if (callbacks) { + callbacks = callbacks.slice(0); // Clone, as the array may be modified during iteration (typically, callbacks will remove themselves) + for (var i = 0; i < callbacks.length; i++) + callbacks[i](node); + } + + // Also erase the DOM data + ko.utils.domData.clear(node); + + // Special support for jQuery here because it's so commonly used. + // Many jQuery plugins (including jquery.tmpl) store data using jQuery's equivalent of domData + // so notify it to tear down any resources associated with the node & descendants here. + if ((typeof jQuery == "function") && (typeof jQuery['cleanData'] == "function")) + jQuery['cleanData']([node]); + + // Also clear any immediate-child comment nodes, as these wouldn't have been found by + // node.getElementsByTagName("*") in cleanNode() (comment nodes aren't elements) + if (cleanableNodeTypesWithDescendants[node.nodeType]) + cleanImmediateCommentTypeChildren(node); + } + + function cleanImmediateCommentTypeChildren(nodeWithChildren) { + var child, nextChild = nodeWithChildren.firstChild; + while (child = nextChild) { + nextChild = child.nextSibling; + if (child.nodeType === 8) + cleanSingleNode(child); + } + } + + return { + addDisposeCallback : function(node, callback) { + if (typeof callback != "function") + throw new Error("Callback must be a function"); + getDisposeCallbacksCollection(node, true).push(callback); + }, + + removeDisposeCallback : function(node, callback) { + var callbacksCollection = getDisposeCallbacksCollection(node, false); + if (callbacksCollection) { + ko.utils.arrayRemoveItem(callbacksCollection, callback); + if (callbacksCollection.length == 0) + destroyCallbacksCollection(node); + } + }, + + cleanNode : function(node) { + // First clean this node, where applicable + if (cleanableNodeTypes[node.nodeType]) { + cleanSingleNode(node); + + // ... then its descendants, where applicable + if (cleanableNodeTypesWithDescendants[node.nodeType]) { + // Clone the descendants list in case it changes during iteration + var descendants = []; + ko.utils.arrayPushAll(descendants, node.getElementsByTagName("*")); + for (var i = 0, j = descendants.length; i < j; i++) + cleanSingleNode(descendants[i]); + } + } + return node; + }, + + removeNode : function(node) { + ko.cleanNode(node); + if (node.parentNode) + node.parentNode.removeChild(node); + } + } +})(); +ko.cleanNode = ko.utils.domNodeDisposal.cleanNode; // Shorthand name for convenience +ko.removeNode = ko.utils.domNodeDisposal.removeNode; // Shorthand name for convenience +ko.exportSymbol('cleanNode', ko.cleanNode); +ko.exportSymbol('removeNode', ko.removeNode); +ko.exportSymbol('utils.domNodeDisposal', ko.utils.domNodeDisposal); +ko.exportSymbol('utils.domNodeDisposal.addDisposeCallback', ko.utils.domNodeDisposal.addDisposeCallback); +ko.exportSymbol('utils.domNodeDisposal.removeDisposeCallback', ko.utils.domNodeDisposal.removeDisposeCallback); +(function () { + var leadingCommentRegex = /^(\s*)<!--(.*?)-->/; + + function simpleHtmlParse(html) { + // Based on jQuery's "clean" function, but only accounting for table-related elements. + // If you have referenced jQuery, this won't be used anyway - KO will use jQuery's "clean" function directly + + // Note that there's still an issue in IE < 9 whereby it will discard comment nodes that are the first child of + // a descendant node. For example: "<div><!-- mycomment -->abc</div>" will get parsed as "<div>abc</div>" + // This won't affect anyone who has referenced jQuery, and there's always the workaround of inserting a dummy node + // (possibly a text node) in front of the comment. So, KO does not attempt to workaround this IE issue automatically at present. + + // Trim whitespace, otherwise indexOf won't work as expected + var tags = ko.utils.stringTrim(html).toLowerCase(), div = document.createElement("div"); + + // Finds the first match from the left column, and returns the corresponding "wrap" data from the right column + var wrap = tags.match(/^<(thead|tbody|tfoot)/) && [1, "<table>", "</table>"] || + !tags.indexOf("<tr") && [2, "<table><tbody>", "</tbody></table>"] || + (!tags.indexOf("<td") || !tags.indexOf("<th")) && [3, "<table><tbody><tr>", "</tr></tbody></table>"] || + /* anything else */ [0, "", ""]; + + // Go to html and back, then peel off extra wrappers + // Note that we always prefix with some dummy text, because otherwise, IE<9 will strip out leading comment nodes in descendants. Total madness. + var markup = "ignored<div>" + wrap[1] + html + wrap[2] + "</div>"; + if (typeof window['innerShiv'] == "function") { + div.appendChild(window['innerShiv'](markup)); + } else { + div.innerHTML = markup; + } + + // Move to the right depth + while (wrap[0]--) + div = div.lastChild; + + return ko.utils.makeArray(div.lastChild.childNodes); + } + + function jQueryHtmlParse(html) { + var elems = jQuery['clean']([html]); + + // As of jQuery 1.7.1, jQuery parses the HTML by appending it to some dummy parent nodes held in an in-memory document fragment. + // Unfortunately, it never clears the dummy parent nodes from the document fragment, so it leaks memory over time. + // Fix this by finding the top-most dummy parent element, and detaching it from its owner fragment. + if (elems && elems[0]) { + // Find the top-most parent element that's a direct child of a document fragment + var elem = elems[0]; + while (elem.parentNode && elem.parentNode.nodeType !== 11 /* i.e., DocumentFragment */) + elem = elem.parentNode; + // ... then detach it + if (elem.parentNode) + elem.parentNode.removeChild(elem); + } + + return elems; + } + + ko.utils.parseHtmlFragment = function(html) { + return typeof jQuery != 'undefined' ? jQueryHtmlParse(html) // As below, benefit from jQuery's optimisations where possible + : simpleHtmlParse(html); // ... otherwise, this simple logic will do in most common cases. + }; + + ko.utils.setHtml = function(node, html) { + ko.utils.emptyDomNode(node); + + // There's no legitimate reason to display a stringified observable without unwrapping it, so we'll unwrap it + html = ko.utils.unwrapObservable(html); + + if ((html !== null) && (html !== undefined)) { + if (typeof html != 'string') + html = html.toString(); + + // jQuery contains a lot of sophisticated code to parse arbitrary HTML fragments, + // for example <tr> elements which are not normally allowed to exist on their own. + // If you've referenced jQuery we'll use that rather than duplicating its code. + if (typeof jQuery != 'undefined') { + jQuery(node)['html'](html); + } else { + // ... otherwise, use KO's own parsing logic. + var parsedNodes = ko.utils.parseHtmlFragment(html); + for (var i = 0; i < parsedNodes.length; i++) + node.appendChild(parsedNodes[i]); + } + } + }; +})(); + +ko.exportSymbol('utils.parseHtmlFragment', ko.utils.parseHtmlFragment); +ko.exportSymbol('utils.setHtml', ko.utils.setHtml); + +ko.memoization = (function () { + var memos = {}; + + function randomMax8HexChars() { + return (((1 + Math.random()) * 0x100000000) | 0).toString(16).substring(1); + } + function generateRandomId() { + return randomMax8HexChars() + randomMax8HexChars(); + } + function findMemoNodes(rootNode, appendToArray) { + if (!rootNode) + return; + if (rootNode.nodeType == 8) { + var memoId = ko.memoization.parseMemoText(rootNode.nodeValue); + if (memoId != null) + appendToArray.push({ domNode: rootNode, memoId: memoId }); + } else if (rootNode.nodeType == 1) { + for (var i = 0, childNodes = rootNode.childNodes, j = childNodes.length; i < j; i++) + findMemoNodes(childNodes[i], appendToArray); + } + } + + return { + memoize: function (callback) { + if (typeof callback != "function") + throw new Error("You can only pass a function to ko.memoization.memoize()"); + var memoId = generateRandomId(); + memos[memoId] = callback; + return "<!--[ko_memo:" + memoId + "]-->"; + }, + + unmemoize: function (memoId, callbackParams) { + var callback = memos[memoId]; + if (callback === undefined) + throw new Error("Couldn't find any memo with ID " + memoId + ". Perhaps it's already been unmemoized."); + try { + callback.apply(null, callbackParams || []); + return true; + } + finally { delete memos[memoId]; } + }, + + unmemoizeDomNodeAndDescendants: function (domNode, extraCallbackParamsArray) { + var memos = []; + findMemoNodes(domNode, memos); + for (var i = 0, j = memos.length; i < j; i++) { + var node = memos[i].domNode; + var combinedParams = [node]; + if (extraCallbackParamsArray) + ko.utils.arrayPushAll(combinedParams, extraCallbackParamsArray); + ko.memoization.unmemoize(memos[i].memoId, combinedParams); + node.nodeValue = ""; // Neuter this node so we don't try to unmemoize it again + if (node.parentNode) + node.parentNode.removeChild(node); // If possible, erase it totally (not always possible - someone else might just hold a reference to it then call unmemoizeDomNodeAndDescendants again) + } + }, + + parseMemoText: function (memoText) { + var match = memoText.match(/^\[ko_memo\:(.*?)\]$/); + return match ? match[1] : null; + } + }; +})(); + +ko.exportSymbol('memoization', ko.memoization); +ko.exportSymbol('memoization.memoize', ko.memoization.memoize); +ko.exportSymbol('memoization.unmemoize', ko.memoization.unmemoize); +ko.exportSymbol('memoization.parseMemoText', ko.memoization.parseMemoText); +ko.exportSymbol('memoization.unmemoizeDomNodeAndDescendants', ko.memoization.unmemoizeDomNodeAndDescendants); +ko.extenders = { + 'throttle': function(target, timeout) { + // Throttling means two things: + + // (1) For dependent observables, we throttle *evaluations* so that, no matter how fast its dependencies + // notify updates, the target doesn't re-evaluate (and hence doesn't notify) faster than a certain rate + target['throttleEvaluation'] = timeout; + + // (2) For writable targets (observables, or writable dependent observables), we throttle *writes* + // so the target cannot change value synchronously or faster than a certain rate + var writeTimeoutInstance = null; + return ko.dependentObservable({ + 'read': target, + 'write': function(value) { + clearTimeout(writeTimeoutInstance); + writeTimeoutInstance = setTimeout(function() { + target(value); + }, timeout); + } + }); + }, + + 'notify': function(target, notifyWhen) { + target["equalityComparer"] = notifyWhen == "always" + ? function() { return false } // Treat all values as not equal + : ko.observable["fn"]["equalityComparer"]; + return target; + } +}; + +function applyExtenders(requestedExtenders) { + var target = this; + if (requestedExtenders) { + for (var key in requestedExtenders) { + var extenderHandler = ko.extenders[key]; + if (typeof extenderHandler == 'function') { + target = extenderHandler(target, requestedExtenders[key]); + } + } + } + return target; +} + +ko.exportSymbol('extenders', ko.extenders); + +ko.subscription = function (target, callback, disposeCallback) { + this.target = target; + this.callback = callback; + this.disposeCallback = disposeCallback; + ko.exportProperty(this, 'dispose', this.dispose); +}; +ko.subscription.prototype.dispose = function () { + this.isDisposed = true; + this.disposeCallback(); +}; + +ko.subscribable = function () { + this._subscriptions = {}; + + ko.utils.extend(this, ko.subscribable['fn']); + ko.exportProperty(this, 'subscribe', this.subscribe); + ko.exportProperty(this, 'extend', this.extend); + ko.exportProperty(this, 'getSubscriptionsCount', this.getSubscriptionsCount); +} + +var defaultEvent = "change"; + +ko.subscribable['fn'] = { + subscribe: function (callback, callbackTarget, event) { + event = event || defaultEvent; + var boundCallback = callbackTarget ? callback.bind(callbackTarget) : callback; + + var subscription = new ko.subscription(this, boundCallback, function () { + ko.utils.arrayRemoveItem(this._subscriptions[event], subscription); + }.bind(this)); + + if (!this._subscriptions[event]) + this._subscriptions[event] = []; + this._subscriptions[event].push(subscription); + return subscription; + }, + + "notifySubscribers": function (valueToNotify, event) { + event = event || defaultEvent; + if (this._subscriptions[event]) { + ko.dependencyDetection.ignore(function() { + ko.utils.arrayForEach(this._subscriptions[event].slice(0), function (subscription) { + // In case a subscription was disposed during the arrayForEach cycle, check + // for isDisposed on each subscription before invoking its callback + if (subscription && (subscription.isDisposed !== true)) + subscription.callback(valueToNotify); + }); + }, this); + } + }, + + getSubscriptionsCount: function () { + var total = 0; + for (var eventName in this._subscriptions) { + if (this._subscriptions.hasOwnProperty(eventName)) + total += this._subscriptions[eventName].length; + } + return total; + }, + + extend: applyExtenders +}; + + +ko.isSubscribable = function (instance) { + return typeof instance.subscribe == "function" && typeof instance["notifySubscribers"] == "function"; +}; + +ko.exportSymbol('subscribable', ko.subscribable); +ko.exportSymbol('isSubscribable', ko.isSubscribable); + +ko.dependencyDetection = (function () { + var _frames = []; + + return { + begin: function (callback) { + _frames.push({ callback: callback, distinctDependencies:[] }); + }, + + end: function () { + _frames.pop(); + }, + + registerDependency: function (subscribable) { + if (!ko.isSubscribable(subscribable)) + throw new Error("Only subscribable things can act as dependencies"); + if (_frames.length > 0) { + var topFrame = _frames[_frames.length - 1]; + if (!topFrame || ko.utils.arrayIndexOf(topFrame.distinctDependencies, subscribable) >= 0) + return; + topFrame.distinctDependencies.push(subscribable); + topFrame.callback(subscribable); + } + }, + + ignore: function(callback, callbackTarget, callbackArgs) { + try { + _frames.push(null); + return callback.apply(callbackTarget, callbackArgs || []); + } finally { + _frames.pop(); + } + } + }; +})(); +var primitiveTypes = { 'undefined':true, 'boolean':true, 'number':true, 'string':true }; + +ko.observable = function (initialValue) { + var _latestValue = initialValue; + + function observable() { + if (arguments.length > 0) { + // Write + + // Ignore writes if the value hasn't changed + if ((!observable['equalityComparer']) || !observable['equalityComparer'](_latestValue, arguments[0])) { + observable.valueWillMutate(); + _latestValue = arguments[0]; + if (DEBUG) observable._latestValue = _latestValue; + observable.valueHasMutated(); + } + return this; // Permits chained assignments + } + else { + // Read + ko.dependencyDetection.registerDependency(observable); // The caller only needs to be notified of changes if they did a "read" operation + return _latestValue; + } + } + if (DEBUG) observable._latestValue = _latestValue; + ko.subscribable.call(observable); + observable.peek = function() { return _latestValue }; + observable.valueHasMutated = function () { observable["notifySubscribers"](_latestValue); } + observable.valueWillMutate = function () { observable["notifySubscribers"](_latestValue, "beforeChange"); } + ko.utils.extend(observable, ko.observable['fn']); + + ko.exportProperty(observable, 'peek', observable.peek); + ko.exportProperty(observable, "valueHasMutated", observable.valueHasMutated); + ko.exportProperty(observable, "valueWillMutate", observable.valueWillMutate); + + return observable; +} + +ko.observable['fn'] = { + "equalityComparer": function valuesArePrimitiveAndEqual(a, b) { + var oldValueIsPrimitive = (a === null) || (typeof(a) in primitiveTypes); + return oldValueIsPrimitive ? (a === b) : false; + } +}; + +var protoProperty = ko.observable.protoProperty = "__ko_proto__"; +ko.observable['fn'][protoProperty] = ko.observable; + +ko.hasPrototype = function(instance, prototype) { + if ((instance === null) || (instance === undefined) || (instance[protoProperty] === undefined)) return false; + if (instance[protoProperty] === prototype) return true; + return ko.hasPrototype(instance[protoProperty], prototype); // Walk the prototype chain +}; + +ko.isObservable = function (instance) { + return ko.hasPrototype(instance, ko.observable); +} +ko.isWriteableObservable = function (instance) { + // Observable + if ((typeof instance == "function") && instance[protoProperty] === ko.observable) + return true; + // Writeable dependent observable + if ((typeof instance == "function") && (instance[protoProperty] === ko.dependentObservable) && (instance.hasWriteFunction)) + return true; + // Anything else + return false; +} + + +ko.exportSymbol('observable', ko.observable); +ko.exportSymbol('isObservable', ko.isObservable); +ko.exportSymbol('isWriteableObservable', ko.isWriteableObservable); +ko.observableArray = function (initialValues) { + if (arguments.length == 0) { + // Zero-parameter constructor initializes to empty array + initialValues = []; + } + if ((initialValues !== null) && (initialValues !== undefined) && !('length' in initialValues)) + throw new Error("The argument passed when initializing an observable array must be an array, or null, or undefined."); + + var result = ko.observable(initialValues); + ko.utils.extend(result, ko.observableArray['fn']); + return result; +} + +ko.observableArray['fn'] = { + 'remove': function (valueOrPredicate) { + var underlyingArray = this.peek(); + var removedValues = []; + var predicate = typeof valueOrPredicate == "function" ? valueOrPredicate : function (value) { return value === valueOrPredicate; }; + for (var i = 0; i < underlyingArray.length; i++) { + var value = underlyingArray[i]; + if (predicate(value)) { + if (removedValues.length === 0) { + this.valueWillMutate(); + } + removedValues.push(value); + underlyingArray.splice(i, 1); + i--; + } + } + if (removedValues.length) { + this.valueHasMutated(); + } + return removedValues; + }, + + 'removeAll': function (arrayOfValues) { + // If you passed zero args, we remove everything + if (arrayOfValues === undefined) { + var underlyingArray = this.peek(); + var allValues = underlyingArray.slice(0); + this.valueWillMutate(); + underlyingArray.splice(0, underlyingArray.length); + this.valueHasMutated(); + return allValues; + } + // If you passed an arg, we interpret it as an array of entries to remove + if (!arrayOfValues) + return []; + return this['remove'](function (value) { + return ko.utils.arrayIndexOf(arrayOfValues, value) >= 0; + }); + }, + + 'destroy': function (valueOrPredicate) { + var underlyingArray = this.peek(); + var predicate = typeof valueOrPredicate == "function" ? valueOrPredicate : function (value) { return value === valueOrPredicate; }; + this.valueWillMutate(); + for (var i = underlyingArray.length - 1; i >= 0; i--) { + var value = underlyingArray[i]; + if (predicate(value)) + underlyingArray[i]["_destroy"] = true; + } + this.valueHasMutated(); + }, + + 'destroyAll': function (arrayOfValues) { + // If you passed zero args, we destroy everything + if (arrayOfValues === undefined) + return this['destroy'](function() { return true }); + + // If you passed an arg, we interpret it as an array of entries to destroy + if (!arrayOfValues) + return []; + return this['destroy'](function (value) { + return ko.utils.arrayIndexOf(arrayOfValues, value) >= 0; + }); + }, + + 'indexOf': function (item) { + var underlyingArray = this(); + return ko.utils.arrayIndexOf(underlyingArray, item); + }, + + 'replace': function(oldItem, newItem) { + var index = this['indexOf'](oldItem); + if (index >= 0) { + this.valueWillMutate(); + this.peek()[index] = newItem; + this.valueHasMutated(); + } + } +} + +// Populate ko.observableArray.fn with read/write functions from native arrays +// Important: Do not add any additional functions here that may reasonably be used to *read* data from the array +// because we'll eval them without causing subscriptions, so ko.computed output could end up getting stale +ko.utils.arrayForEach(["pop", "push", "reverse", "shift", "sort", "splice", "unshift"], function (methodName) { + ko.observableArray['fn'][methodName] = function () { + // Use "peek" to avoid creating a subscription in any computed that we're executing in the context of + // (for consistency with mutating regular observables) + var underlyingArray = this.peek(); + this.valueWillMutate(); + var methodCallResult = underlyingArray[methodName].apply(underlyingArray, arguments); + this.valueHasMutated(); + return methodCallResult; + }; +}); + +// Populate ko.observableArray.fn with read-only functions from native arrays +ko.utils.arrayForEach(["slice"], function (methodName) { + ko.observableArray['fn'][methodName] = function () { + var underlyingArray = this(); + return underlyingArray[methodName].apply(underlyingArray, arguments); + }; +}); + +ko.exportSymbol('observableArray', ko.observableArray); +ko.dependentObservable = function (evaluatorFunctionOrOptions, evaluatorFunctionTarget, options) { + var _latestValue, + _hasBeenEvaluated = false, + _isBeingEvaluated = false, + readFunction = evaluatorFunctionOrOptions; + + if (readFunction && typeof readFunction == "object") { + // Single-parameter syntax - everything is on this "options" param + options = readFunction; + readFunction = options["read"]; + } else { + // Multi-parameter syntax - construct the options according to the params passed + options = options || {}; + if (!readFunction) + readFunction = options["read"]; + } + if (typeof readFunction != "function") + throw new Error("Pass a function that returns the value of the ko.computed"); + + function addSubscriptionToDependency(subscribable) { + _subscriptionsToDependencies.push(subscribable.subscribe(evaluatePossiblyAsync)); + } + + function disposeAllSubscriptionsToDependencies() { + ko.utils.arrayForEach(_subscriptionsToDependencies, function (subscription) { + subscription.dispose(); + }); + _subscriptionsToDependencies = []; + } + + function evaluatePossiblyAsync() { + var throttleEvaluationTimeout = dependentObservable['throttleEvaluation']; + if (throttleEvaluationTimeout && throttleEvaluationTimeout >= 0) { + clearTimeout(evaluationTimeoutInstance); + evaluationTimeoutInstance = setTimeout(evaluateImmediate, throttleEvaluationTimeout); + } else + evaluateImmediate(); + } + + function evaluateImmediate() { + if (_isBeingEvaluated) { + // If the evaluation of a ko.computed causes side effects, it's possible that it will trigger its own re-evaluation. + // This is not desirable (it's hard for a developer to realise a chain of dependencies might cause this, and they almost + // certainly didn't intend infinite re-evaluations). So, for predictability, we simply prevent ko.computeds from causing + // their own re-evaluation. Further discussion at https://github.com/SteveSanderson/knockout/pull/387 + return; + } + + // Don't dispose on first evaluation, because the "disposeWhen" callback might + // e.g., dispose when the associated DOM element isn't in the doc, and it's not + // going to be in the doc until *after* the first evaluation + if (_hasBeenEvaluated && disposeWhen()) { + dispose(); + return; + } + + _isBeingEvaluated = true; + try { + // Initially, we assume that none of the subscriptions are still being used (i.e., all are candidates for disposal). + // Then, during evaluation, we cross off any that are in fact still being used. + var disposalCandidates = ko.utils.arrayMap(_subscriptionsToDependencies, function(item) {return item.target;}); + + ko.dependencyDetection.begin(function(subscribable) { + var inOld; + if ((inOld = ko.utils.arrayIndexOf(disposalCandidates, subscribable)) >= 0) + disposalCandidates[inOld] = undefined; // Don't want to dispose this subscription, as it's still being used + else + addSubscriptionToDependency(subscribable); // Brand new subscription - add it + }); + + var newValue = readFunction.call(evaluatorFunctionTarget); + + // For each subscription no longer being used, remove it from the active subscriptions list and dispose it + for (var i = disposalCandidates.length - 1; i >= 0; i--) { + if (disposalCandidates[i]) + _subscriptionsToDependencies.splice(i, 1)[0].dispose(); + } + _hasBeenEvaluated = true; + + dependentObservable["notifySubscribers"](_latestValue, "beforeChange"); + _latestValue = newValue; + if (DEBUG) dependentObservable._latestValue = _latestValue; + } finally { + ko.dependencyDetection.end(); + } + + dependentObservable["notifySubscribers"](_latestValue); + _isBeingEvaluated = false; + if (!_subscriptionsToDependencies.length) + dispose(); + } + + function dependentObservable() { + if (arguments.length > 0) { + if (typeof writeFunction === "function") { + // Writing a value + writeFunction.apply(evaluatorFunctionTarget, arguments); + } else { + throw new Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters."); + } + return this; // Permits chained assignments + } else { + // Reading the value + if (!_hasBeenEvaluated) + evaluateImmediate(); + ko.dependencyDetection.registerDependency(dependentObservable); + return _latestValue; + } + } + + function peek() { + if (!_hasBeenEvaluated) + evaluateImmediate(); + return _latestValue; + } + + function isActive() { + return !_hasBeenEvaluated || _subscriptionsToDependencies.length > 0; + } + + // By here, "options" is always non-null + var writeFunction = options["write"], + disposeWhenNodeIsRemoved = options["disposeWhenNodeIsRemoved"] || options.disposeWhenNodeIsRemoved || null, + disposeWhen = options["disposeWhen"] || options.disposeWhen || function() { return false; }, + dispose = disposeAllSubscriptionsToDependencies, + _subscriptionsToDependencies = [], + evaluationTimeoutInstance = null; + + if (!evaluatorFunctionTarget) + evaluatorFunctionTarget = options["owner"]; + + dependentObservable.peek = peek; + dependentObservable.getDependenciesCount = function () { return _subscriptionsToDependencies.length; }; + dependentObservable.hasWriteFunction = typeof options["write"] === "function"; + dependentObservable.dispose = function () { dispose(); }; + dependentObservable.isActive = isActive; + + ko.subscribable.call(dependentObservable); + ko.utils.extend(dependentObservable, ko.dependentObservable['fn']); + + ko.exportProperty(dependentObservable, 'peek', dependentObservable.peek); + ko.exportProperty(dependentObservable, 'dispose', dependentObservable.dispose); + ko.exportProperty(dependentObservable, 'isActive', dependentObservable.isActive); + ko.exportProperty(dependentObservable, 'getDependenciesCount', dependentObservable.getDependenciesCount); + + // Evaluate, unless deferEvaluation is true + if (options['deferEvaluation'] !== true) + evaluateImmediate(); + + // Build "disposeWhenNodeIsRemoved" and "disposeWhenNodeIsRemovedCallback" option values. + // But skip if isActive is false (there will never be any dependencies to dispose). + // (Note: "disposeWhenNodeIsRemoved" option both proactively disposes as soon as the node is removed using ko.removeNode(), + // plus adds a "disposeWhen" callback that, on each evaluation, disposes if the node was removed by some other means.) + if (disposeWhenNodeIsRemoved && isActive()) { + dispose = function() { + ko.utils.domNodeDisposal.removeDisposeCallback(disposeWhenNodeIsRemoved, arguments.callee); + disposeAllSubscriptionsToDependencies(); + }; + ko.utils.domNodeDisposal.addDisposeCallback(disposeWhenNodeIsRemoved, dispose); + var existingDisposeWhenFunction = disposeWhen; + disposeWhen = function () { + return !ko.utils.domNodeIsAttachedToDocument(disposeWhenNodeIsRemoved) || existingDisposeWhenFunction(); + } + } + + return dependentObservable; +}; + +ko.isComputed = function(instance) { + return ko.hasPrototype(instance, ko.dependentObservable); +}; + +var protoProp = ko.observable.protoProperty; // == "__ko_proto__" +ko.dependentObservable[protoProp] = ko.observable; + +ko.dependentObservable['fn'] = {}; +ko.dependentObservable['fn'][protoProp] = ko.dependentObservable; + +ko.exportSymbol('dependentObservable', ko.dependentObservable); +ko.exportSymbol('computed', ko.dependentObservable); // Make "ko.computed" an alias for "ko.dependentObservable" +ko.exportSymbol('isComputed', ko.isComputed); + +(function() { + var maxNestedObservableDepth = 10; // Escape the (unlikely) pathalogical case where an observable's current value is itself (or similar reference cycle) + + ko.toJS = function(rootObject) { + if (arguments.length == 0) + throw new Error("When calling ko.toJS, pass the object you want to convert."); + + // We just unwrap everything at every level in the object graph + return mapJsObjectGraph(rootObject, function(valueToMap) { + // Loop because an observable's value might in turn be another observable wrapper + for (var i = 0; ko.isObservable(valueToMap) && (i < maxNestedObservableDepth); i++) + valueToMap = valueToMap(); + return valueToMap; + }); + }; + + ko.toJSON = function(rootObject, replacer, space) { // replacer and space are optional + var plainJavaScriptObject = ko.toJS(rootObject); + return ko.utils.stringifyJson(plainJavaScriptObject, replacer, space); + }; + + function mapJsObjectGraph(rootObject, mapInputCallback, visitedObjects) { + visitedObjects = visitedObjects || new objectLookup(); + + rootObject = mapInputCallback(rootObject); + var canHaveProperties = (typeof rootObject == "object") && (rootObject !== null) && (rootObject !== undefined) && (!(rootObject instanceof Date)); + if (!canHaveProperties) + return rootObject; + + var outputProperties = rootObject instanceof Array ? [] : {}; + visitedObjects.save(rootObject, outputProperties); + + visitPropertiesOrArrayEntries(rootObject, function(indexer) { + var propertyValue = mapInputCallback(rootObject[indexer]); + + switch (typeof propertyValue) { + case "boolean": + case "number": + case "string": + case "function": + outputProperties[indexer] = propertyValue; + break; + case "object": + case "undefined": + var previouslyMappedValue = visitedObjects.get(propertyValue); + outputProperties[indexer] = (previouslyMappedValue !== undefined) + ? previouslyMappedValue + : mapJsObjectGraph(propertyValue, mapInputCallback, visitedObjects); + break; + } + }); + + return outputProperties; + } + + function visitPropertiesOrArrayEntries(rootObject, visitorCallback) { + if (rootObject instanceof Array) { + for (var i = 0; i < rootObject.length; i++) + visitorCallback(i); + + // For arrays, also respect toJSON property for custom mappings (fixes #278) + if (typeof rootObject['toJSON'] == 'function') + visitorCallback('toJSON'); + } else { + for (var propertyName in rootObject) + visitorCallback(propertyName); + } + }; + + function objectLookup() { + var keys = []; + var values = []; + this.save = function(key, value) { + var existingIndex = ko.utils.arrayIndexOf(keys, key); + if (existingIndex >= 0) + values[existingIndex] = value; + else { + keys.push(key); + values.push(value); + } + }; + this.get = function(key) { + var existingIndex = ko.utils.arrayIndexOf(keys, key); + return (existingIndex >= 0) ? values[existingIndex] : undefined; + }; + }; +})(); + +ko.exportSymbol('toJS', ko.toJS); +ko.exportSymbol('toJSON', ko.toJSON); +(function () { + var hasDomDataExpandoProperty = '__ko__hasDomDataOptionValue__'; + + // Normally, SELECT elements and their OPTIONs can only take value of type 'string' (because the values + // are stored on DOM attributes). ko.selectExtensions provides a way for SELECTs/OPTIONs to have values + // that are arbitrary objects. This is very convenient when implementing things like cascading dropdowns. + ko.selectExtensions = { + readValue : function(element) { + switch (ko.utils.tagNameLower(element)) { + case 'option': + if (element[hasDomDataExpandoProperty] === true) + return ko.utils.domData.get(element, ko.bindingHandlers.options.optionValueDomDataKey); + return ko.utils.ieVersion <= 7 + ? (element.getAttributeNode('value').specified ? element.value : element.text) + : element.value; + case 'select': + return element.selectedIndex >= 0 ? ko.selectExtensions.readValue(element.options[element.selectedIndex]) : undefined; + default: + return element.value; + } + }, + + writeValue: function(element, value) { + switch (ko.utils.tagNameLower(element)) { + case 'option': + switch(typeof value) { + case "string": + ko.utils.domData.set(element, ko.bindingHandlers.options.optionValueDomDataKey, undefined); + if (hasDomDataExpandoProperty in element) { // IE <= 8 throws errors if you delete non-existent properties from a DOM node + delete element[hasDomDataExpandoProperty]; + } + element.value = value; + break; + default: + // Store arbitrary object using DomData + ko.utils.domData.set(element, ko.bindingHandlers.options.optionValueDomDataKey, value); + element[hasDomDataExpandoProperty] = true; + + // Special treatment of numbers is just for backward compatibility. KO 1.2.1 wrote numerical values to element.value. + element.value = typeof value === "number" ? value : ""; + break; + } + break; + case 'select': + for (var i = element.options.length - 1; i >= 0; i--) { + if (ko.selectExtensions.readValue(element.options[i]) == value) { + element.selectedIndex = i; + break; + } + } + break; + default: + if ((value === null) || (value === undefined)) + value = ""; + element.value = value; + break; + } + } + }; +})(); + +ko.exportSymbol('selectExtensions', ko.selectExtensions); +ko.exportSymbol('selectExtensions.readValue', ko.selectExtensions.readValue); +ko.exportSymbol('selectExtensions.writeValue', ko.selectExtensions.writeValue); +ko.expressionRewriting = (function () { + var restoreCapturedTokensRegex = /\@ko_token_(\d+)\@/g; + var javaScriptReservedWords = ["true", "false"]; + + // Matches something that can be assigned to--either an isolated identifier or something ending with a property accessor + // This is designed to be simple and avoid false negatives, but could produce false positives (e.g., a+b.c). + var javaScriptAssignmentTarget = /^(?:[$_a-z][$\w]*|(.+)(\.\s*[$_a-z][$\w]*|\[.+\]))$/i; + + function restoreTokens(string, tokens) { + var prevValue = null; + while (string != prevValue) { // Keep restoring tokens until it no longer makes a difference (they may be nested) + prevValue = string; + string = string.replace(restoreCapturedTokensRegex, function (match, tokenIndex) { + return tokens[tokenIndex]; + }); + } + return string; + } + + function getWriteableValue(expression) { + if (ko.utils.arrayIndexOf(javaScriptReservedWords, ko.utils.stringTrim(expression).toLowerCase()) >= 0) + return false; + var match = expression.match(javaScriptAssignmentTarget); + return match === null ? false : match[1] ? ('Object(' + match[1] + ')' + match[2]) : expression; + } + + function ensureQuoted(key) { + var trimmedKey = ko.utils.stringTrim(key); + switch (trimmedKey.length && trimmedKey.charAt(0)) { + case "'": + case '"': + return key; + default: + return "'" + trimmedKey + "'"; + } + } + + return { + bindingRewriteValidators: [], + + parseObjectLiteral: function(objectLiteralString) { + // A full tokeniser+lexer would add too much weight to this library, so here's a simple parser + // that is sufficient just to split an object literal string into a set of top-level key-value pairs + + var str = ko.utils.stringTrim(objectLiteralString); + if (str.length < 3) + return []; + if (str.charAt(0) === "{")// Ignore any braces surrounding the whole object literal + str = str.substring(1, str.length - 1); + + // Pull out any string literals and regex literals + var tokens = []; + var tokenStart = null, tokenEndChar; + for (var position = 0; position < str.length; position++) { + var c = str.charAt(position); + if (tokenStart === null) { + switch (c) { + case '"': + case "'": + case "/": + tokenStart = position; + tokenEndChar = c; + break; + } + } else if ((c == tokenEndChar) && (str.charAt(position - 1) !== "\\")) { + var token = str.substring(tokenStart, position + 1); + tokens.push(token); + var replacement = "@ko_token_" + (tokens.length - 1) + "@"; + str = str.substring(0, tokenStart) + replacement + str.substring(position + 1); + position -= (token.length - replacement.length); + tokenStart = null; + } + } + + // Next pull out balanced paren, brace, and bracket blocks + tokenStart = null; + tokenEndChar = null; + var tokenDepth = 0, tokenStartChar = null; + for (var position = 0; position < str.length; position++) { + var c = str.charAt(position); + if (tokenStart === null) { + switch (c) { + case "{": tokenStart = position; tokenStartChar = c; + tokenEndChar = "}"; + break; + case "(": tokenStart = position; tokenStartChar = c; + tokenEndChar = ")"; + break; + case "[": tokenStart = position; tokenStartChar = c; + tokenEndChar = "]"; + break; + } + } + + if (c === tokenStartChar) + tokenDepth++; + else if (c === tokenEndChar) { + tokenDepth--; + if (tokenDepth === 0) { + var token = str.substring(tokenStart, position + 1); + tokens.push(token); + var replacement = "@ko_token_" + (tokens.length - 1) + "@"; + str = str.substring(0, tokenStart) + replacement + str.substring(position + 1); + position -= (token.length - replacement.length); + tokenStart = null; + } + } + } + + // Now we can safely split on commas to get the key/value pairs + var result = []; + var keyValuePairs = str.split(","); + for (var i = 0, j = keyValuePairs.length; i < j; i++) { + var pair = keyValuePairs[i]; + var colonPos = pair.indexOf(":"); + if ((colonPos > 0) && (colonPos < pair.length - 1)) { + var key = pair.substring(0, colonPos); + var value = pair.substring(colonPos + 1); + result.push({ 'key': restoreTokens(key, tokens), 'value': restoreTokens(value, tokens) }); + } else { + result.push({ 'unknown': restoreTokens(pair, tokens) }); + } + } + return result; + }, + + preProcessBindings: function (objectLiteralStringOrKeyValueArray) { + var keyValueArray = typeof objectLiteralStringOrKeyValueArray === "string" + ? ko.expressionRewriting.parseObjectLiteral(objectLiteralStringOrKeyValueArray) + : objectLiteralStringOrKeyValueArray; + var resultStrings = [], propertyAccessorResultStrings = []; + + var keyValueEntry; + for (var i = 0; keyValueEntry = keyValueArray[i]; i++) { + if (resultStrings.length > 0) + resultStrings.push(","); + + if (keyValueEntry['key']) { + var quotedKey = ensureQuoted(keyValueEntry['key']), val = keyValueEntry['value']; + resultStrings.push(quotedKey); + resultStrings.push(":"); + resultStrings.push(val); + + if (val = getWriteableValue(ko.utils.stringTrim(val))) { + if (propertyAccessorResultStrings.length > 0) + propertyAccessorResultStrings.push(", "); + propertyAccessorResultStrings.push(quotedKey + " : function(__ko_value) { " + val + " = __ko_value; }"); + } + } else if (keyValueEntry['unknown']) { + resultStrings.push(keyValueEntry['unknown']); + } + } + + var combinedResult = resultStrings.join(""); + if (propertyAccessorResultStrings.length > 0) { + var allPropertyAccessors = propertyAccessorResultStrings.join(""); + combinedResult = combinedResult + ", '_ko_property_writers' : { " + allPropertyAccessors + " } "; + } + + return combinedResult; + }, + + keyValueArrayContainsKey: function(keyValueArray, key) { + for (var i = 0; i < keyValueArray.length; i++) + if (ko.utils.stringTrim(keyValueArray[i]['key']) == key) + return true; + return false; + }, + + // Internal, private KO utility for updating model properties from within bindings + // property: If the property being updated is (or might be) an observable, pass it here + // If it turns out to be a writable observable, it will be written to directly + // allBindingsAccessor: All bindings in the current execution context. + // This will be searched for a '_ko_property_writers' property in case you're writing to a non-observable + // key: The key identifying the property to be written. Example: for { hasFocus: myValue }, write to 'myValue' by specifying the key 'hasFocus' + // value: The value to be written + // checkIfDifferent: If true, and if the property being written is a writable observable, the value will only be written if + // it is !== existing value on that writable observable + writeValueToProperty: function(property, allBindingsAccessor, key, value, checkIfDifferent) { + if (!property || !ko.isWriteableObservable(property)) { + var propWriters = allBindingsAccessor()['_ko_property_writers']; + if (propWriters && propWriters[key]) + propWriters[key](value); + } else if (!checkIfDifferent || property.peek() !== value) { + property(value); + } + } + }; +})(); + +ko.exportSymbol('expressionRewriting', ko.expressionRewriting); +ko.exportSymbol('expressionRewriting.bindingRewriteValidators', ko.expressionRewriting.bindingRewriteValidators); +ko.exportSymbol('expressionRewriting.parseObjectLiteral', ko.expressionRewriting.parseObjectLiteral); +ko.exportSymbol('expressionRewriting.preProcessBindings', ko.expressionRewriting.preProcessBindings); + +// For backward compatibility, define the following aliases. (Previously, these function names were misleading because +// they referred to JSON specifically, even though they actually work with arbitrary JavaScript object literal expressions.) +ko.exportSymbol('jsonExpressionRewriting', ko.expressionRewriting); +ko.exportSymbol('jsonExpressionRewriting.insertPropertyAccessorsIntoJson', ko.expressionRewriting.preProcessBindings);(function() { + // "Virtual elements" is an abstraction on top of the usual DOM API which understands the notion that comment nodes + // may be used to represent hierarchy (in addition to the DOM's natural hierarchy). + // If you call the DOM-manipulating functions on ko.virtualElements, you will be able to read and write the state + // of that virtual hierarchy + // + // The point of all this is to support containerless templates (e.g., <!-- ko foreach:someCollection -->blah<!-- /ko -->) + // without having to scatter special cases all over the binding and templating code. + + // IE 9 cannot reliably read the "nodeValue" property of a comment node (see https://github.com/SteveSanderson/knockout/issues/186) + // but it does give them a nonstandard alternative property called "text" that it can read reliably. Other browsers don't have that property. + // So, use node.text where available, and node.nodeValue elsewhere + var commentNodesHaveTextProperty = document.createComment("test").text === "<!--test-->"; + + var startCommentRegex = commentNodesHaveTextProperty ? /^<!--\s*ko(?:\s+(.+\s*\:[\s\S]*))?\s*-->$/ : /^\s*ko(?:\s+(.+\s*\:[\s\S]*))?\s*$/; + var endCommentRegex = commentNodesHaveTextProperty ? /^<!--\s*\/ko\s*-->$/ : /^\s*\/ko\s*$/; + var htmlTagsWithOptionallyClosingChildren = { 'ul': true, 'ol': true }; + + function isStartComment(node) { + return (node.nodeType == 8) && (commentNodesHaveTextProperty ? node.text : node.nodeValue).match(startCommentRegex); + } + + function isEndComment(node) { + return (node.nodeType == 8) && (commentNodesHaveTextProperty ? node.text : node.nodeValue).match(endCommentRegex); + } + + function getVirtualChildren(startComment, allowUnbalanced) { + var currentNode = startComment; + var depth = 1; + var children = []; + while (currentNode = currentNode.nextSibling) { + if (isEndComment(currentNode)) { + depth--; + if (depth === 0) + return children; + } + + children.push(currentNode); + + if (isStartComment(currentNode)) + depth++; + } + if (!allowUnbalanced) + throw new Error("Cannot find closing comment tag to match: " + startComment.nodeValue); + return null; + } + + function getMatchingEndComment(startComment, allowUnbalanced) { + var allVirtualChildren = getVirtualChildren(startComment, allowUnbalanced); + if (allVirtualChildren) { + if (allVirtualChildren.length > 0) + return allVirtualChildren[allVirtualChildren.length - 1].nextSibling; + return startComment.nextSibling; + } else + return null; // Must have no matching end comment, and allowUnbalanced is true + } + + function getUnbalancedChildTags(node) { + // e.g., from <div>OK</div><!-- ko blah --><span>Another</span>, returns: <!-- ko blah --><span>Another</span> + // from <div>OK</div><!-- /ko --><!-- /ko -->, returns: <!-- /ko --><!-- /ko --> + var childNode = node.firstChild, captureRemaining = null; + if (childNode) { + do { + if (captureRemaining) // We already hit an unbalanced node and are now just scooping up all subsequent nodes + captureRemaining.push(childNode); + else if (isStartComment(childNode)) { + var matchingEndComment = getMatchingEndComment(childNode, /* allowUnbalanced: */ true); + if (matchingEndComment) // It's a balanced tag, so skip immediately to the end of this virtual set + childNode = matchingEndComment; + else + captureRemaining = [childNode]; // It's unbalanced, so start capturing from this point + } else if (isEndComment(childNode)) { + captureRemaining = [childNode]; // It's unbalanced (if it wasn't, we'd have skipped over it already), so start capturing + } + } while (childNode = childNode.nextSibling); + } + return captureRemaining; + } + + ko.virtualElements = { + allowedBindings: {}, + + childNodes: function(node) { + return isStartComment(node) ? getVirtualChildren(node) : node.childNodes; + }, + + emptyNode: function(node) { + if (!isStartComment(node)) + ko.utils.emptyDomNode(node); + else { + var virtualChildren = ko.virtualElements.childNodes(node); + for (var i = 0, j = virtualChildren.length; i < j; i++) + ko.removeNode(virtualChildren[i]); + } + }, + + setDomNodeChildren: function(node, childNodes) { + if (!isStartComment(node)) + ko.utils.setDomNodeChildren(node, childNodes); + else { + ko.virtualElements.emptyNode(node); + var endCommentNode = node.nextSibling; // Must be the next sibling, as we just emptied the children + for (var i = 0, j = childNodes.length; i < j; i++) + endCommentNode.parentNode.insertBefore(childNodes[i], endCommentNode); + } + }, + + prepend: function(containerNode, nodeToPrepend) { + if (!isStartComment(containerNode)) { + if (containerNode.firstChild) + containerNode.insertBefore(nodeToPrepend, containerNode.firstChild); + else + containerNode.appendChild(nodeToPrepend); + } else { + // Start comments must always have a parent and at least one following sibling (the end comment) + containerNode.parentNode.insertBefore(nodeToPrepend, containerNode.nextSibling); + } + }, + + insertAfter: function(containerNode, nodeToInsert, insertAfterNode) { + if (!insertAfterNode) { + ko.virtualElements.prepend(containerNode, nodeToInsert); + } else if (!isStartComment(containerNode)) { + // Insert after insertion point + if (insertAfterNode.nextSibling) + containerNode.insertBefore(nodeToInsert, insertAfterNode.nextSibling); + else + containerNode.appendChild(nodeToInsert); + } else { + // Children of start comments must always have a parent and at least one following sibling (the end comment) + containerNode.parentNode.insertBefore(nodeToInsert, insertAfterNode.nextSibling); + } + }, + + firstChild: function(node) { + if (!isStartComment(node)) + return node.firstChild; + if (!node.nextSibling || isEndComment(node.nextSibling)) + return null; + return node.nextSibling; + }, + + nextSibling: function(node) { + if (isStartComment(node)) + node = getMatchingEndComment(node); + if (node.nextSibling && isEndComment(node.nextSibling)) + return null; + return node.nextSibling; + }, + + virtualNodeBindingValue: function(node) { + var regexMatch = isStartComment(node); + return regexMatch ? regexMatch[1] : null; + }, + + normaliseVirtualElementDomStructure: function(elementVerified) { + // Workaround for https://github.com/SteveSanderson/knockout/issues/155 + // (IE <= 8 or IE 9 quirks mode parses your HTML weirdly, treating closing </li> tags as if they don't exist, thereby moving comment nodes + // that are direct descendants of <ul> into the preceding <li>) + if (!htmlTagsWithOptionallyClosingChildren[ko.utils.tagNameLower(elementVerified)]) + return; + + // Scan immediate children to see if they contain unbalanced comment tags. If they do, those comment tags + // must be intended to appear *after* that child, so move them there. + var childNode = elementVerified.firstChild; + if (childNode) { + do { + if (childNode.nodeType === 1) { + var unbalancedTags = getUnbalancedChildTags(childNode); + if (unbalancedTags) { + // Fix up the DOM by moving the unbalanced tags to where they most likely were intended to be placed - *after* the child + var nodeToInsertBefore = childNode.nextSibling; + for (var i = 0; i < unbalancedTags.length; i++) { + if (nodeToInsertBefore) + elementVerified.insertBefore(unbalancedTags[i], nodeToInsertBefore); + else + elementVerified.appendChild(unbalancedTags[i]); + } + } + } + } while (childNode = childNode.nextSibling); + } + } + }; +})(); +ko.exportSymbol('virtualElements', ko.virtualElements); +ko.exportSymbol('virtualElements.allowedBindings', ko.virtualElements.allowedBindings); +ko.exportSymbol('virtualElements.emptyNode', ko.virtualElements.emptyNode); +//ko.exportSymbol('virtualElements.firstChild', ko.virtualElements.firstChild); // firstChild is not minified +ko.exportSymbol('virtualElements.insertAfter', ko.virtualElements.insertAfter); +//ko.exportSymbol('virtualElements.nextSibling', ko.virtualElements.nextSibling); // nextSibling is not minified +ko.exportSymbol('virtualElements.prepend', ko.virtualElements.prepend); +ko.exportSymbol('virtualElements.setDomNodeChildren', ko.virtualElements.setDomNodeChildren); +(function() { + var defaultBindingAttributeName = "data-bind"; + + ko.bindingProvider = function() { + this.bindingCache = {}; + }; + + ko.utils.extend(ko.bindingProvider.prototype, { + 'nodeHasBindings': function(node) { + switch (node.nodeType) { + case 1: return node.getAttribute(defaultBindingAttributeName) != null; // Element + case 8: return ko.virtualElements.virtualNodeBindingValue(node) != null; // Comment node + default: return false; + } + }, + + 'getBindings': function(node, bindingContext) { + var bindingsString = this['getBindingsString'](node, bindingContext); + return bindingsString ? this['parseBindingsString'](bindingsString, bindingContext, node) : null; + }, + + // The following function is only used internally by this default provider. + // It's not part of the interface definition for a general binding provider. + 'getBindingsString': function(node, bindingContext) { + switch (node.nodeType) { + case 1: return node.getAttribute(defaultBindingAttributeName); // Element + case 8: return ko.virtualElements.virtualNodeBindingValue(node); // Comment node + default: return null; + } + }, + + // The following function is only used internally by this default provider. + // It's not part of the interface definition for a general binding provider. + 'parseBindingsString': function(bindingsString, bindingContext, node) { + try { + var bindingFunction = createBindingsStringEvaluatorViaCache(bindingsString, this.bindingCache); + return bindingFunction(bindingContext, node); + } catch (ex) { + throw new Error("Unable to parse bindings.\nMessage: " + ex + ";\nBindings value: " + bindingsString); + } + } + }); + + ko.bindingProvider['instance'] = new ko.bindingProvider(); + + function createBindingsStringEvaluatorViaCache(bindingsString, cache) { + var cacheKey = bindingsString; + return cache[cacheKey] + || (cache[cacheKey] = createBindingsStringEvaluator(bindingsString)); + } + + function createBindingsStringEvaluator(bindingsString) { + // Build the source for a function that evaluates "expression" + // For each scope variable, add an extra level of "with" nesting + // Example result: with(sc1) { with(sc0) { return (expression) } } + var rewrittenBindings = ko.expressionRewriting.preProcessBindings(bindingsString), + functionBody = "with($context){with($data||{}){return{" + rewrittenBindings + "}}}"; + return new Function("$context", "$element", functionBody); + } +})(); + +ko.exportSymbol('bindingProvider', ko.bindingProvider); +(function () { + ko.bindingHandlers = {}; + + ko.bindingContext = function(dataItem, parentBindingContext, dataItemAlias) { + if (parentBindingContext) { + ko.utils.extend(this, parentBindingContext); // Inherit $root and any custom properties + this['$parentContext'] = parentBindingContext; + this['$parent'] = parentBindingContext['$data']; + this['$parents'] = (parentBindingContext['$parents'] || []).slice(0); + this['$parents'].unshift(this['$parent']); + } else { + this['$parents'] = []; + this['$root'] = dataItem; + // Export 'ko' in the binding context so it will be available in bindings and templates + // even if 'ko' isn't exported as a global, such as when using an AMD loader. + // See https://github.com/SteveSanderson/knockout/issues/490 + this['ko'] = ko; + } + this['$data'] = dataItem; + if (dataItemAlias) + this[dataItemAlias] = dataItem; + } + ko.bindingContext.prototype['createChildContext'] = function (dataItem, dataItemAlias) { + return new ko.bindingContext(dataItem, this, dataItemAlias); + }; + ko.bindingContext.prototype['extend'] = function(properties) { + var clone = ko.utils.extend(new ko.bindingContext(), this); + return ko.utils.extend(clone, properties); + }; + + function validateThatBindingIsAllowedForVirtualElements(bindingName) { + var validator = ko.virtualElements.allowedBindings[bindingName]; + if (!validator) + throw new Error("The binding '" + bindingName + "' cannot be used with virtual elements") + } + + function applyBindingsToDescendantsInternal (viewModel, elementOrVirtualElement, bindingContextsMayDifferFromDomParentElement) { + var currentChild, nextInQueue = ko.virtualElements.firstChild(elementOrVirtualElement); + while (currentChild = nextInQueue) { + // Keep a record of the next child *before* applying bindings, in case the binding removes the current child from its position + nextInQueue = ko.virtualElements.nextSibling(currentChild); + applyBindingsToNodeAndDescendantsInternal(viewModel, currentChild, bindingContextsMayDifferFromDomParentElement); + } + } + + function applyBindingsToNodeAndDescendantsInternal (viewModel, nodeVerified, bindingContextMayDifferFromDomParentElement) { + var shouldBindDescendants = true; + + // Perf optimisation: Apply bindings only if... + // (1) We need to store the binding context on this node (because it may differ from the DOM parent node's binding context) + // Note that we can't store binding contexts on non-elements (e.g., text nodes), as IE doesn't allow expando properties for those + // (2) It might have bindings (e.g., it has a data-bind attribute, or it's a marker for a containerless template) + var isElement = (nodeVerified.nodeType === 1); + if (isElement) // Workaround IE <= 8 HTML parsing weirdness + ko.virtualElements.normaliseVirtualElementDomStructure(nodeVerified); + + var shouldApplyBindings = (isElement && bindingContextMayDifferFromDomParentElement) // Case (1) + || ko.bindingProvider['instance']['nodeHasBindings'](nodeVerified); // Case (2) + if (shouldApplyBindings) + shouldBindDescendants = applyBindingsToNodeInternal(nodeVerified, null, viewModel, bindingContextMayDifferFromDomParentElement).shouldBindDescendants; + + if (shouldBindDescendants) { + // We're recursing automatically into (real or virtual) child nodes without changing binding contexts. So, + // * For children of a *real* element, the binding context is certainly the same as on their DOM .parentNode, + // hence bindingContextsMayDifferFromDomParentElement is false + // * For children of a *virtual* element, we can't be sure. Evaluating .parentNode on those children may + // skip over any number of intermediate virtual elements, any of which might define a custom binding context, + // hence bindingContextsMayDifferFromDomParentElement is true + applyBindingsToDescendantsInternal(viewModel, nodeVerified, /* bindingContextsMayDifferFromDomParentElement: */ !isElement); + } + } + + function applyBindingsToNodeInternal (node, bindings, viewModelOrBindingContext, bindingContextMayDifferFromDomParentElement) { + // Need to be sure that inits are only run once, and updates never run until all the inits have been run + var initPhase = 0; // 0 = before all inits, 1 = during inits, 2 = after all inits + + // Each time the dependentObservable is evaluated (after data changes), + // the binding attribute is reparsed so that it can pick out the correct + // model properties in the context of the changed data. + // DOM event callbacks need to be able to access this changed data, + // so we need a single parsedBindings variable (shared by all callbacks + // associated with this node's bindings) that all the closures can access. + var parsedBindings; + function makeValueAccessor(bindingKey) { + return function () { return parsedBindings[bindingKey] } + } + function parsedBindingsAccessor() { + return parsedBindings; + } + + var bindingHandlerThatControlsDescendantBindings; + ko.dependentObservable( + function () { + // Ensure we have a nonnull binding context to work with + var bindingContextInstance = viewModelOrBindingContext && (viewModelOrBindingContext instanceof ko.bindingContext) + ? viewModelOrBindingContext + : new ko.bindingContext(ko.utils.unwrapObservable(viewModelOrBindingContext)); + var viewModel = bindingContextInstance['$data']; + + // Optimization: Don't store the binding context on this node if it's definitely the same as on node.parentNode, because + // we can easily recover it just by scanning up the node's ancestors in the DOM + // (note: here, parent node means "real DOM parent" not "virtual parent", as there's no O(1) way to find the virtual parent) + if (bindingContextMayDifferFromDomParentElement) + ko.storedBindingContextForNode(node, bindingContextInstance); + + // Use evaluatedBindings if given, otherwise fall back on asking the bindings provider to give us some bindings + var evaluatedBindings = (typeof bindings == "function") ? bindings(bindingContextInstance, node) : bindings; + parsedBindings = evaluatedBindings || ko.bindingProvider['instance']['getBindings'](node, bindingContextInstance); + + if (parsedBindings) { + // First run all the inits, so bindings can register for notification on changes + if (initPhase === 0) { + initPhase = 1; + for (var bindingKey in parsedBindings) { + var binding = ko.bindingHandlers[bindingKey]; + if (binding && node.nodeType === 8) + validateThatBindingIsAllowedForVirtualElements(bindingKey); + + if (binding && typeof binding["init"] == "function") { + var handlerInitFn = binding["init"]; + var initResult = handlerInitFn(node, makeValueAccessor(bindingKey), parsedBindingsAccessor, viewModel, bindingContextInstance); + + // If this binding handler claims to control descendant bindings, make a note of this + if (initResult && initResult['controlsDescendantBindings']) { + if (bindingHandlerThatControlsDescendantBindings !== undefined) + throw new Error("Multiple bindings (" + bindingHandlerThatControlsDescendantBindings + " and " + bindingKey + ") are trying to control descendant bindings of the same element. You cannot use these bindings together on the same element."); + bindingHandlerThatControlsDescendantBindings = bindingKey; + } + } + } + initPhase = 2; + } + + // ... then run all the updates, which might trigger changes even on the first evaluation + if (initPhase === 2) { + for (var bindingKey in parsedBindings) { + var binding = ko.bindingHandlers[bindingKey]; + if (binding && typeof binding["update"] == "function") { + var handlerUpdateFn = binding["update"]; + handlerUpdateFn(node, makeValueAccessor(bindingKey), parsedBindingsAccessor, viewModel, bindingContextInstance); + } + } + } + } + }, + null, + { disposeWhenNodeIsRemoved : node } + ); + + return { + shouldBindDescendants: bindingHandlerThatControlsDescendantBindings === undefined + }; + }; + + var storedBindingContextDomDataKey = "__ko_bindingContext__"; + ko.storedBindingContextForNode = function (node, bindingContext) { + if (arguments.length == 2) + ko.utils.domData.set(node, storedBindingContextDomDataKey, bindingContext); + else + return ko.utils.domData.get(node, storedBindingContextDomDataKey); + } + + ko.applyBindingsToNode = function (node, bindings, viewModel) { + if (node.nodeType === 1) // If it's an element, workaround IE <= 8 HTML parsing weirdness + ko.virtualElements.normaliseVirtualElementDomStructure(node); + return applyBindingsToNodeInternal(node, bindings, viewModel, true); + }; + + ko.applyBindingsToDescendants = function(viewModel, rootNode) { + if (rootNode.nodeType === 1 || rootNode.nodeType === 8) + applyBindingsToDescendantsInternal(viewModel, rootNode, true); + }; + + ko.applyBindings = function (viewModel, rootNode) { + if (rootNode && (rootNode.nodeType !== 1) && (rootNode.nodeType !== 8)) + throw new Error("ko.applyBindings: first parameter should be your view model; second parameter should be a DOM node"); + rootNode = rootNode || window.document.body; // Make "rootNode" parameter optional + + applyBindingsToNodeAndDescendantsInternal(viewModel, rootNode, true); + }; + + // Retrieving binding context from arbitrary nodes + ko.contextFor = function(node) { + // We can only do something meaningful for elements and comment nodes (in particular, not text nodes, as IE can't store domdata for them) + switch (node.nodeType) { + case 1: + case 8: + var context = ko.storedBindingContextForNode(node); + if (context) return context; + if (node.parentNode) return ko.contextFor(node.parentNode); + break; + } + return undefined; + }; + ko.dataFor = function(node) { + var context = ko.contextFor(node); + return context ? context['$data'] : undefined; + }; + + ko.exportSymbol('bindingHandlers', ko.bindingHandlers); + ko.exportSymbol('applyBindings', ko.applyBindings); + ko.exportSymbol('applyBindingsToDescendants', ko.applyBindingsToDescendants); + ko.exportSymbol('applyBindingsToNode', ko.applyBindingsToNode); + ko.exportSymbol('contextFor', ko.contextFor); + ko.exportSymbol('dataFor', ko.dataFor); +})(); +var attrHtmlToJavascriptMap = { 'class': 'className', 'for': 'htmlFor' }; +ko.bindingHandlers['attr'] = { + 'update': function(element, valueAccessor, allBindingsAccessor) { + var value = ko.utils.unwrapObservable(valueAccessor()) || {}; + for (var attrName in value) { + if (typeof attrName == "string") { + var attrValue = ko.utils.unwrapObservable(value[attrName]); + + // To cover cases like "attr: { checked:someProp }", we want to remove the attribute entirely + // when someProp is a "no value"-like value (strictly null, false, or undefined) + // (because the absence of the "checked" attr is how to mark an element as not checked, etc.) + var toRemove = (attrValue === false) || (attrValue === null) || (attrValue === undefined); + if (toRemove) + element.removeAttribute(attrName); + + // In IE <= 7 and IE8 Quirks Mode, you have to use the Javascript property name instead of the + // HTML attribute name for certain attributes. IE8 Standards Mode supports the correct behavior, + // but instead of figuring out the mode, we'll just set the attribute through the Javascript + // property for IE <= 8. + if (ko.utils.ieVersion <= 8 && attrName in attrHtmlToJavascriptMap) { + attrName = attrHtmlToJavascriptMap[attrName]; + if (toRemove) + element.removeAttribute(attrName); + else + element[attrName] = attrValue; + } else if (!toRemove) { + element.setAttribute(attrName, attrValue.toString()); + } + + // Treat "name" specially - although you can think of it as an attribute, it also needs + // special handling on older versions of IE (https://github.com/SteveSanderson/knockout/pull/333) + // Deliberately being case-sensitive here because XHTML would regard "Name" as a different thing + // entirely, and there's no strong reason to allow for such casing in HTML. + if (attrName === "name") { + ko.utils.setElementName(element, toRemove ? "" : attrValue.toString()); + } + } + } + } +}; +ko.bindingHandlers['checked'] = { + 'init': function (element, valueAccessor, allBindingsAccessor) { + var updateHandler = function() { + var valueToWrite; + if (element.type == "checkbox") { + valueToWrite = element.checked; + } else if ((element.type == "radio") && (element.checked)) { + valueToWrite = element.value; + } else { + return; // "checked" binding only responds to checkboxes and selected radio buttons + } + + var modelValue = valueAccessor(), unwrappedValue = ko.utils.unwrapObservable(modelValue); + if ((element.type == "checkbox") && (unwrappedValue instanceof Array)) { + // For checkboxes bound to an array, we add/remove the checkbox value to that array + // This works for both observable and non-observable arrays + var existingEntryIndex = ko.utils.arrayIndexOf(unwrappedValue, element.value); + if (element.checked && (existingEntryIndex < 0)) + modelValue.push(element.value); + else if ((!element.checked) && (existingEntryIndex >= 0)) + modelValue.splice(existingEntryIndex, 1); + } else { + ko.expressionRewriting.writeValueToProperty(modelValue, allBindingsAccessor, 'checked', valueToWrite, true); + } + }; + ko.utils.registerEventHandler(element, "click", updateHandler); + + // IE 6 won't allow radio buttons to be selected unless they have a name + if ((element.type == "radio") && !element.name) + ko.bindingHandlers['uniqueName']['init'](element, function() { return true }); + }, + 'update': function (element, valueAccessor) { + var value = ko.utils.unwrapObservable(valueAccessor()); + + if (element.type == "checkbox") { + if (value instanceof Array) { + // When bound to an array, the checkbox being checked represents its value being present in that array + element.checked = ko.utils.arrayIndexOf(value, element.value) >= 0; + } else { + // When bound to anything other value (not an array), the checkbox being checked represents the value being trueish + element.checked = value; + } + } else if (element.type == "radio") { + element.checked = (element.value == value); + } + } +}; +var classesWrittenByBindingKey = '__ko__cssValue'; +ko.bindingHandlers['css'] = { + 'update': function (element, valueAccessor) { + var value = ko.utils.unwrapObservable(valueAccessor()); + if (typeof value == "object") { + for (var className in value) { + var shouldHaveClass = ko.utils.unwrapObservable(value[className]); + ko.utils.toggleDomNodeCssClass(element, className, shouldHaveClass); + } + } else { + value = String(value || ''); // Make sure we don't try to store or set a non-string value + ko.utils.toggleDomNodeCssClass(element, element[classesWrittenByBindingKey], false); + element[classesWrittenByBindingKey] = value; + ko.utils.toggleDomNodeCssClass(element, value, true); + } + } +}; +ko.bindingHandlers['enable'] = { + 'update': function (element, valueAccessor) { + var value = ko.utils.unwrapObservable(valueAccessor()); + if (value && element.disabled) + element.removeAttribute("disabled"); + else if ((!value) && (!element.disabled)) + element.disabled = true; + } +}; + +ko.bindingHandlers['disable'] = { + 'update': function (element, valueAccessor) { + ko.bindingHandlers['enable']['update'](element, function() { return !ko.utils.unwrapObservable(valueAccessor()) }); + } +}; +// For certain common events (currently just 'click'), allow a simplified data-binding syntax +// e.g. click:handler instead of the usual full-length event:{click:handler} +function makeEventHandlerShortcut(eventName) { + ko.bindingHandlers[eventName] = { + 'init': function(element, valueAccessor, allBindingsAccessor, viewModel) { + var newValueAccessor = function () { + var result = {}; + result[eventName] = valueAccessor(); + return result; + }; + return ko.bindingHandlers['event']['init'].call(this, element, newValueAccessor, allBindingsAccessor, viewModel); + } + } +} + +ko.bindingHandlers['event'] = { + 'init' : function (element, valueAccessor, allBindingsAccessor, viewModel) { + var eventsToHandle = valueAccessor() || {}; + for(var eventNameOutsideClosure in eventsToHandle) { + (function() { + var eventName = eventNameOutsideClosure; // Separate variable to be captured by event handler closure + if (typeof eventName == "string") { + ko.utils.registerEventHandler(element, eventName, function (event) { + var handlerReturnValue; + var handlerFunction = valueAccessor()[eventName]; + if (!handlerFunction) + return; + var allBindings = allBindingsAccessor(); + + try { + // Take all the event args, and prefix with the viewmodel + var argsForHandler = ko.utils.makeArray(arguments); + argsForHandler.unshift(viewModel); + handlerReturnValue = handlerFunction.apply(viewModel, argsForHandler); + } finally { + if (handlerReturnValue !== true) { // Normally we want to prevent default action. Developer can override this be explicitly returning true. + if (event.preventDefault) + event.preventDefault(); + else + event.returnValue = false; + } + } + + var bubble = allBindings[eventName + 'Bubble'] !== false; + if (!bubble) { + event.cancelBubble = true; + if (event.stopPropagation) + event.stopPropagation(); + } + }); + } + })(); + } + } +}; +// "foreach: someExpression" is equivalent to "template: { foreach: someExpression }" +// "foreach: { data: someExpression, afterAdd: myfn }" is equivalent to "template: { foreach: someExpression, afterAdd: myfn }" +ko.bindingHandlers['foreach'] = { + makeTemplateValueAccessor: function(valueAccessor) { + return function() { + var modelValue = valueAccessor(), + unwrappedValue = ko.utils.peekObservable(modelValue); // Unwrap without setting a dependency here + + // If unwrappedValue is the array, pass in the wrapped value on its own + // The value will be unwrapped and tracked within the template binding + // (See https://github.com/SteveSanderson/knockout/issues/523) + if ((!unwrappedValue) || typeof unwrappedValue.length == "number") + return { 'foreach': modelValue, 'templateEngine': ko.nativeTemplateEngine.instance }; + + // If unwrappedValue.data is the array, preserve all relevant options and unwrap again value so we get updates + ko.utils.unwrapObservable(modelValue); + return { + 'foreach': unwrappedValue['data'], + 'as': unwrappedValue['as'], + 'includeDestroyed': unwrappedValue['includeDestroyed'], + 'afterAdd': unwrappedValue['afterAdd'], + 'beforeRemove': unwrappedValue['beforeRemove'], + 'afterRender': unwrappedValue['afterRender'], + 'beforeMove': unwrappedValue['beforeMove'], + 'afterMove': unwrappedValue['afterMove'], + 'templateEngine': ko.nativeTemplateEngine.instance + }; + }; + }, + 'init': function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { + return ko.bindingHandlers['template']['init'](element, ko.bindingHandlers['foreach'].makeTemplateValueAccessor(valueAccessor)); + }, + 'update': function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { + return ko.bindingHandlers['template']['update'](element, ko.bindingHandlers['foreach'].makeTemplateValueAccessor(valueAccessor), allBindingsAccessor, viewModel, bindingContext); + } +}; +ko.expressionRewriting.bindingRewriteValidators['foreach'] = false; // Can't rewrite control flow bindings +ko.virtualElements.allowedBindings['foreach'] = true; +var hasfocusUpdatingProperty = '__ko_hasfocusUpdating'; +ko.bindingHandlers['hasfocus'] = { + 'init': function(element, valueAccessor, allBindingsAccessor) { + var handleElementFocusChange = function(isFocused) { + // Where possible, ignore which event was raised and determine focus state using activeElement, + // as this avoids phantom focus/blur events raised when changing tabs in modern browsers. + // However, not all KO-targeted browsers (Firefox 2) support activeElement. For those browsers, + // prevent a loss of focus when changing tabs/windows by setting a flag that prevents hasfocus + // from calling 'blur()' on the element when it loses focus. + // Discussion at https://github.com/SteveSanderson/knockout/pull/352 + element[hasfocusUpdatingProperty] = true; + var ownerDoc = element.ownerDocument; + if ("activeElement" in ownerDoc) { + isFocused = (ownerDoc.activeElement === element); + } + var modelValue = valueAccessor(); + ko.expressionRewriting.writeValueToProperty(modelValue, allBindingsAccessor, 'hasfocus', isFocused, true); + element[hasfocusUpdatingProperty] = false; + }; + var handleElementFocusIn = handleElementFocusChange.bind(null, true); + var handleElementFocusOut = handleElementFocusChange.bind(null, false); + + ko.utils.registerEventHandler(element, "focus", handleElementFocusIn); + ko.utils.registerEventHandler(element, "focusin", handleElementFocusIn); // For IE + ko.utils.registerEventHandler(element, "blur", handleElementFocusOut); + ko.utils.registerEventHandler(element, "focusout", handleElementFocusOut); // For IE + }, + 'update': function(element, valueAccessor) { + var value = ko.utils.unwrapObservable(valueAccessor()); + if (!element[hasfocusUpdatingProperty]) { + value ? element.focus() : element.blur(); + ko.dependencyDetection.ignore(ko.utils.triggerEvent, null, [element, value ? "focusin" : "focusout"]); // For IE, which doesn't reliably fire "focus" or "blur" events synchronously + } + } +}; +ko.bindingHandlers['html'] = { + 'init': function() { + // Prevent binding on the dynamically-injected HTML (as developers are unlikely to expect that, and it has security implications) + return { 'controlsDescendantBindings': true }; + }, + 'update': function (element, valueAccessor) { + // setHtml will unwrap the value if needed + ko.utils.setHtml(element, valueAccessor()); + } +}; +var withIfDomDataKey = '__ko_withIfBindingData'; +// Makes a binding like with or if +function makeWithIfBinding(bindingKey, isWith, isNot, makeContextCallback) { + ko.bindingHandlers[bindingKey] = { + 'init': function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { + ko.utils.domData.set(element, withIfDomDataKey, {}); + return { 'controlsDescendantBindings': true }; + }, + 'update': function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { + var withIfData = ko.utils.domData.get(element, withIfDomDataKey), + dataValue = ko.utils.unwrapObservable(valueAccessor()), + shouldDisplay = !isNot !== !dataValue, // equivalent to isNot ? !dataValue : !!dataValue + isFirstRender = !withIfData.savedNodes, + needsRefresh = isFirstRender || isWith || (shouldDisplay !== withIfData.didDisplayOnLastUpdate); + + if (needsRefresh) { + if (isFirstRender) { + withIfData.savedNodes = ko.utils.cloneNodes(ko.virtualElements.childNodes(element), true /* shouldCleanNodes */); + } + + if (shouldDisplay) { + if (!isFirstRender) { + ko.virtualElements.setDomNodeChildren(element, ko.utils.cloneNodes(withIfData.savedNodes)); + } + ko.applyBindingsToDescendants(makeContextCallback ? makeContextCallback(bindingContext, dataValue) : bindingContext, element); + } else { + ko.virtualElements.emptyNode(element); + } + + withIfData.didDisplayOnLastUpdate = shouldDisplay; + } + } + }; + ko.expressionRewriting.bindingRewriteValidators[bindingKey] = false; // Can't rewrite control flow bindings + ko.virtualElements.allowedBindings[bindingKey] = true; +} + +// Construct the actual binding handlers +makeWithIfBinding('if'); +makeWithIfBinding('ifnot', false /* isWith */, true /* isNot */); +makeWithIfBinding('with', true /* isWith */, false /* isNot */, + function(bindingContext, dataValue) { + return bindingContext['createChildContext'](dataValue); + } +); +function ensureDropdownSelectionIsConsistentWithModelValue(element, modelValue, preferModelValue) { + if (preferModelValue) { + if (modelValue !== ko.selectExtensions.readValue(element)) + ko.selectExtensions.writeValue(element, modelValue); + } + + // No matter which direction we're syncing in, we want the end result to be equality between dropdown value and model value. + // If they aren't equal, either we prefer the dropdown value, or the model value couldn't be represented, so either way, + // change the model value to match the dropdown. + if (modelValue !== ko.selectExtensions.readValue(element)) + ko.dependencyDetection.ignore(ko.utils.triggerEvent, null, [element, "change"]); +}; + +ko.bindingHandlers['options'] = { + 'update': function (element, valueAccessor, allBindingsAccessor) { + if (ko.utils.tagNameLower(element) !== "select") + throw new Error("options binding applies only to SELECT elements"); + + var selectWasPreviouslyEmpty = element.length == 0; + var previousSelectedValues = ko.utils.arrayMap(ko.utils.arrayFilter(element.childNodes, function (node) { + return node.tagName && (ko.utils.tagNameLower(node) === "option") && node.selected; + }), function (node) { + return ko.selectExtensions.readValue(node) || node.innerText || node.textContent; + }); + var previousScrollTop = element.scrollTop; + + var value = ko.utils.unwrapObservable(valueAccessor()); + var selectedValue = element.value; + + // Remove all existing <option>s. + // Need to use .remove() rather than .removeChild() for <option>s otherwise IE behaves oddly (https://github.com/SteveSanderson/knockout/issues/134) + while (element.length > 0) { + ko.cleanNode(element.options[0]); + element.remove(0); + } + + if (value) { + var allBindings = allBindingsAccessor(), + includeDestroyed = allBindings['optionsIncludeDestroyed']; + + if (typeof value.length != "number") + value = [value]; + if (allBindings['optionsCaption']) { + var option = document.createElement("option"); + ko.utils.setHtml(option, allBindings['optionsCaption']); + ko.selectExtensions.writeValue(option, undefined); + element.appendChild(option); + } + + for (var i = 0, j = value.length; i < j; i++) { + // Skip destroyed items + var arrayEntry = value[i]; + if (arrayEntry && arrayEntry['_destroy'] && !includeDestroyed) + continue; + + var option = document.createElement("option"); + + function applyToObject(object, predicate, defaultValue) { + var predicateType = typeof predicate; + if (predicateType == "function") // Given a function; run it against the data value + return predicate(object); + else if (predicateType == "string") // Given a string; treat it as a property name on the data value + return object[predicate]; + else // Given no optionsText arg; use the data value itself + return defaultValue; + } + + // Apply a value to the option element + var optionValue = applyToObject(arrayEntry, allBindings['optionsValue'], arrayEntry); + ko.selectExtensions.writeValue(option, ko.utils.unwrapObservable(optionValue)); + + // Apply some text to the option element + var optionText = applyToObject(arrayEntry, allBindings['optionsText'], optionValue); + ko.utils.setTextContent(option, optionText); + + element.appendChild(option); + } + + // IE6 doesn't like us to assign selection to OPTION nodes before they're added to the document. + // That's why we first added them without selection. Now it's time to set the selection. + var newOptions = element.getElementsByTagName("option"); + var countSelectionsRetained = 0; + for (var i = 0, j = newOptions.length; i < j; i++) { + if (ko.utils.arrayIndexOf(previousSelectedValues, ko.selectExtensions.readValue(newOptions[i])) >= 0) { + ko.utils.setOptionNodeSelectionState(newOptions[i], true); + countSelectionsRetained++; + } + } + + element.scrollTop = previousScrollTop; + + if (selectWasPreviouslyEmpty && ('value' in allBindings)) { + // Ensure consistency between model value and selected option. + // If the dropdown is being populated for the first time here (or was otherwise previously empty), + // the dropdown selection state is meaningless, so we preserve the model value. + ensureDropdownSelectionIsConsistentWithModelValue(element, ko.utils.peekObservable(allBindings['value']), /* preferModelValue */ true); + } + + // Workaround for IE9 bug + ko.utils.ensureSelectElementIsRenderedCorrectly(element); + } + } +}; +ko.bindingHandlers['options'].optionValueDomDataKey = '__ko.optionValueDomData__'; +ko.bindingHandlers['selectedOptions'] = { + 'init': function (element, valueAccessor, allBindingsAccessor) { + ko.utils.registerEventHandler(element, "change", function () { + var value = valueAccessor(), valueToWrite = []; + ko.utils.arrayForEach(element.getElementsByTagName("option"), function(node) { + if (node.selected) + valueToWrite.push(ko.selectExtensions.readValue(node)); + }); + ko.expressionRewriting.writeValueToProperty(value, allBindingsAccessor, 'value', valueToWrite); + }); + }, + 'update': function (element, valueAccessor) { + if (ko.utils.tagNameLower(element) != "select") + throw new Error("values binding applies only to SELECT elements"); + + var newValue = ko.utils.unwrapObservable(valueAccessor()); + if (newValue && typeof newValue.length == "number") { + ko.utils.arrayForEach(element.getElementsByTagName("option"), function(node) { + var isSelected = ko.utils.arrayIndexOf(newValue, ko.selectExtensions.readValue(node)) >= 0; + ko.utils.setOptionNodeSelectionState(node, isSelected); + }); + } + } +}; +ko.bindingHandlers['style'] = { + 'update': function (element, valueAccessor) { + var value = ko.utils.unwrapObservable(valueAccessor() || {}); + for (var styleName in value) { + if (typeof styleName == "string") { + var styleValue = ko.utils.unwrapObservable(value[styleName]); + element.style[styleName] = styleValue || ""; // Empty string removes the value, whereas null/undefined have no effect + } + } + } +}; +ko.bindingHandlers['submit'] = { + 'init': function (element, valueAccessor, allBindingsAccessor, viewModel) { + if (typeof valueAccessor() != "function") + throw new Error("The value for a submit binding must be a function"); + ko.utils.registerEventHandler(element, "submit", function (event) { + var handlerReturnValue; + var value = valueAccessor(); + try { handlerReturnValue = value.call(viewModel, element); } + finally { + if (handlerReturnValue !== true) { // Normally we want to prevent default action. Developer can override this be explicitly returning true. + if (event.preventDefault) + event.preventDefault(); + else + event.returnValue = false; + } + } + }); + } +}; +ko.bindingHandlers['text'] = { + 'update': function (element, valueAccessor) { + ko.utils.setTextContent(element, valueAccessor()); + } +}; +ko.virtualElements.allowedBindings['text'] = true; +ko.bindingHandlers['uniqueName'] = { + 'init': function (element, valueAccessor) { + if (valueAccessor()) { + var name = "ko_unique_" + (++ko.bindingHandlers['uniqueName'].currentIndex); + ko.utils.setElementName(element, name); + } + } +}; +ko.bindingHandlers['uniqueName'].currentIndex = 0; +ko.bindingHandlers['value'] = { + 'init': function (element, valueAccessor, allBindingsAccessor) { + // Always catch "change" event; possibly other events too if asked + var eventsToCatch = ["change"]; + var requestedEventsToCatch = allBindingsAccessor()["valueUpdate"]; + var propertyChangedFired = false; + if (requestedEventsToCatch) { + if (typeof requestedEventsToCatch == "string") // Allow both individual event names, and arrays of event names + requestedEventsToCatch = [requestedEventsToCatch]; + ko.utils.arrayPushAll(eventsToCatch, requestedEventsToCatch); + eventsToCatch = ko.utils.arrayGetDistinctValues(eventsToCatch); + } + + var valueUpdateHandler = function() { + propertyChangedFired = false; + var modelValue = valueAccessor(); + var elementValue = ko.selectExtensions.readValue(element); + ko.expressionRewriting.writeValueToProperty(modelValue, allBindingsAccessor, 'value', elementValue); + } + + // Workaround for https://github.com/SteveSanderson/knockout/issues/122 + // IE doesn't fire "change" events on textboxes if the user selects a value from its autocomplete list + var ieAutoCompleteHackNeeded = ko.utils.ieVersion && element.tagName.toLowerCase() == "input" && element.type == "text" + && element.autocomplete != "off" && (!element.form || element.form.autocomplete != "off"); + if (ieAutoCompleteHackNeeded && ko.utils.arrayIndexOf(eventsToCatch, "propertychange") == -1) { + ko.utils.registerEventHandler(element, "propertychange", function () { propertyChangedFired = true }); + ko.utils.registerEventHandler(element, "blur", function() { + if (propertyChangedFired) { + valueUpdateHandler(); + } + }); + } + + ko.utils.arrayForEach(eventsToCatch, function(eventName) { + // The syntax "after<eventname>" means "run the handler asynchronously after the event" + // This is useful, for example, to catch "keydown" events after the browser has updated the control + // (otherwise, ko.selectExtensions.readValue(this) will receive the control's value *before* the key event) + var handler = valueUpdateHandler; + if (ko.utils.stringStartsWith(eventName, "after")) { + handler = function() { setTimeout(valueUpdateHandler, 0) }; + eventName = eventName.substring("after".length); + } + ko.utils.registerEventHandler(element, eventName, handler); + }); + }, + 'update': function (element, valueAccessor) { + var valueIsSelectOption = ko.utils.tagNameLower(element) === "select"; + var newValue = ko.utils.unwrapObservable(valueAccessor()); + var elementValue = ko.selectExtensions.readValue(element); + var valueHasChanged = (newValue != elementValue); + + // JavaScript's 0 == "" behavious is unfortunate here as it prevents writing 0 to an empty text box (loose equality suggests the values are the same). + // We don't want to do a strict equality comparison as that is more confusing for developers in certain cases, so we specifically special case 0 != "" here. + if ((newValue === 0) && (elementValue !== 0) && (elementValue !== "0")) + valueHasChanged = true; + + if (valueHasChanged) { + var applyValueAction = function () { ko.selectExtensions.writeValue(element, newValue); }; + applyValueAction(); + + // Workaround for IE6 bug: It won't reliably apply values to SELECT nodes during the same execution thread + // right after you've changed the set of OPTION nodes on it. So for that node type, we'll schedule a second thread + // to apply the value as well. + var alsoApplyAsynchronously = valueIsSelectOption; + if (alsoApplyAsynchronously) + setTimeout(applyValueAction, 0); + } + + // If you try to set a model value that can't be represented in an already-populated dropdown, reject that change, + // because you're not allowed to have a model value that disagrees with a visible UI selection. + if (valueIsSelectOption && (element.length > 0)) + ensureDropdownSelectionIsConsistentWithModelValue(element, newValue, /* preferModelValue */ false); + } +}; +ko.bindingHandlers['visible'] = { + 'update': function (element, valueAccessor) { + var value = ko.utils.unwrapObservable(valueAccessor()); + var isCurrentlyVisible = !(element.style.display == "none"); + if (value && !isCurrentlyVisible) + element.style.display = ""; + else if ((!value) && isCurrentlyVisible) + element.style.display = "none"; + } +}; +// 'click' is just a shorthand for the usual full-length event:{click:handler} +makeEventHandlerShortcut('click'); +// If you want to make a custom template engine, +// +// [1] Inherit from this class (like ko.nativeTemplateEngine does) +// [2] Override 'renderTemplateSource', supplying a function with this signature: +// +// function (templateSource, bindingContext, options) { +// // - templateSource.text() is the text of the template you should render +// // - bindingContext.$data is the data you should pass into the template +// // - you might also want to make bindingContext.$parent, bindingContext.$parents, +// // and bindingContext.$root available in the template too +// // - options gives you access to any other properties set on "data-bind: { template: options }" +// // +// // Return value: an array of DOM nodes +// } +// +// [3] Override 'createJavaScriptEvaluatorBlock', supplying a function with this signature: +// +// function (script) { +// // Return value: Whatever syntax means "Evaluate the JavaScript statement 'script' and output the result" +// // For example, the jquery.tmpl template engine converts 'someScript' to '${ someScript }' +// } +// +// This is only necessary if you want to allow data-bind attributes to reference arbitrary template variables. +// If you don't want to allow that, you can set the property 'allowTemplateRewriting' to false (like ko.nativeTemplateEngine does) +// and then you don't need to override 'createJavaScriptEvaluatorBlock'. + +ko.templateEngine = function () { }; + +ko.templateEngine.prototype['renderTemplateSource'] = function (templateSource, bindingContext, options) { + throw new Error("Override renderTemplateSource"); +}; + +ko.templateEngine.prototype['createJavaScriptEvaluatorBlock'] = function (script) { + throw new Error("Override createJavaScriptEvaluatorBlock"); +}; + +ko.templateEngine.prototype['makeTemplateSource'] = function(template, templateDocument) { + // Named template + if (typeof template == "string") { + templateDocument = templateDocument || document; + var elem = templateDocument.getElementById(template); + if (!elem) + throw new Error("Cannot find template with ID " + template); + return new ko.templateSources.domElement(elem); + } else if ((template.nodeType == 1) || (template.nodeType == 8)) { + // Anonymous template + return new ko.templateSources.anonymousTemplate(template); + } else + throw new Error("Unknown template type: " + template); +}; + +ko.templateEngine.prototype['renderTemplate'] = function (template, bindingContext, options, templateDocument) { + var templateSource = this['makeTemplateSource'](template, templateDocument); + return this['renderTemplateSource'](templateSource, bindingContext, options); +}; + +ko.templateEngine.prototype['isTemplateRewritten'] = function (template, templateDocument) { + // Skip rewriting if requested + if (this['allowTemplateRewriting'] === false) + return true; + return this['makeTemplateSource'](template, templateDocument)['data']("isRewritten"); +}; + +ko.templateEngine.prototype['rewriteTemplate'] = function (template, rewriterCallback, templateDocument) { + var templateSource = this['makeTemplateSource'](template, templateDocument); + var rewritten = rewriterCallback(templateSource['text']()); + templateSource['text'](rewritten); + templateSource['data']("isRewritten", true); +}; + +ko.exportSymbol('templateEngine', ko.templateEngine); + +ko.templateRewriting = (function () { + var memoizeDataBindingAttributeSyntaxRegex = /(<[a-z]+\d*(\s+(?!data-bind=)[a-z0-9\-]+(=(\"[^\"]*\"|\'[^\']*\'))?)*\s+)data-bind=(["'])([\s\S]*?)\5/gi; + var memoizeVirtualContainerBindingSyntaxRegex = /<!--\s*ko\b\s*([\s\S]*?)\s*-->/g; + + function validateDataBindValuesForRewriting(keyValueArray) { + var allValidators = ko.expressionRewriting.bindingRewriteValidators; + for (var i = 0; i < keyValueArray.length; i++) { + var key = keyValueArray[i]['key']; + if (allValidators.hasOwnProperty(key)) { + var validator = allValidators[key]; + + if (typeof validator === "function") { + var possibleErrorMessage = validator(keyValueArray[i]['value']); + if (possibleErrorMessage) + throw new Error(possibleErrorMessage); + } else if (!validator) { + throw new Error("This template engine does not support the '" + key + "' binding within its templates"); + } + } + } + } + + function constructMemoizedTagReplacement(dataBindAttributeValue, tagToRetain, templateEngine) { + var dataBindKeyValueArray = ko.expressionRewriting.parseObjectLiteral(dataBindAttributeValue); + validateDataBindValuesForRewriting(dataBindKeyValueArray); + var rewrittenDataBindAttributeValue = ko.expressionRewriting.preProcessBindings(dataBindKeyValueArray); + + // For no obvious reason, Opera fails to evaluate rewrittenDataBindAttributeValue unless it's wrapped in an additional + // anonymous function, even though Opera's built-in debugger can evaluate it anyway. No other browser requires this + // extra indirection. + var applyBindingsToNextSiblingScript = + "ko.__tr_ambtns(function($context,$element){return(function(){return{ " + rewrittenDataBindAttributeValue + " } })()})"; + return templateEngine['createJavaScriptEvaluatorBlock'](applyBindingsToNextSiblingScript) + tagToRetain; + } + + return { + ensureTemplateIsRewritten: function (template, templateEngine, templateDocument) { + if (!templateEngine['isTemplateRewritten'](template, templateDocument)) + templateEngine['rewriteTemplate'](template, function (htmlString) { + return ko.templateRewriting.memoizeBindingAttributeSyntax(htmlString, templateEngine); + }, templateDocument); + }, + + memoizeBindingAttributeSyntax: function (htmlString, templateEngine) { + return htmlString.replace(memoizeDataBindingAttributeSyntaxRegex, function () { + return constructMemoizedTagReplacement(/* dataBindAttributeValue: */ arguments[6], /* tagToRetain: */ arguments[1], templateEngine); + }).replace(memoizeVirtualContainerBindingSyntaxRegex, function() { + return constructMemoizedTagReplacement(/* dataBindAttributeValue: */ arguments[1], /* tagToRetain: */ "<!-- ko -->", templateEngine); + }); + }, + + applyMemoizedBindingsToNextSibling: function (bindings) { + return ko.memoization.memoize(function (domNode, bindingContext) { + if (domNode.nextSibling) + ko.applyBindingsToNode(domNode.nextSibling, bindings, bindingContext); + }); + } + } +})(); + + +// Exported only because it has to be referenced by string lookup from within rewritten template +ko.exportSymbol('__tr_ambtns', ko.templateRewriting.applyMemoizedBindingsToNextSibling); +(function() { + // A template source represents a read/write way of accessing a template. This is to eliminate the need for template loading/saving + // logic to be duplicated in every template engine (and means they can all work with anonymous templates, etc.) + // + // Two are provided by default: + // 1. ko.templateSources.domElement - reads/writes the text content of an arbitrary DOM element + // 2. ko.templateSources.anonymousElement - uses ko.utils.domData to read/write text *associated* with the DOM element, but + // without reading/writing the actual element text content, since it will be overwritten + // with the rendered template output. + // You can implement your own template source if you want to fetch/store templates somewhere other than in DOM elements. + // Template sources need to have the following functions: + // text() - returns the template text from your storage location + // text(value) - writes the supplied template text to your storage location + // data(key) - reads values stored using data(key, value) - see below + // data(key, value) - associates "value" with this template and the key "key". Is used to store information like "isRewritten". + // + // Optionally, template sources can also have the following functions: + // nodes() - returns a DOM element containing the nodes of this template, where available + // nodes(value) - writes the given DOM element to your storage location + // If a DOM element is available for a given template source, template engines are encouraged to use it in preference over text() + // for improved speed. However, all templateSources must supply text() even if they don't supply nodes(). + // + // Once you've implemented a templateSource, make your template engine use it by subclassing whatever template engine you were + // using and overriding "makeTemplateSource" to return an instance of your custom template source. + + ko.templateSources = {}; + + // ---- ko.templateSources.domElement ----- + + ko.templateSources.domElement = function(element) { + this.domElement = element; + } + + ko.templateSources.domElement.prototype['text'] = function(/* valueToWrite */) { + var tagNameLower = ko.utils.tagNameLower(this.domElement), + elemContentsProperty = tagNameLower === "script" ? "text" + : tagNameLower === "textarea" ? "value" + : "innerHTML"; + + if (arguments.length == 0) { + return this.domElement[elemContentsProperty]; + } else { + var valueToWrite = arguments[0]; + if (elemContentsProperty === "innerHTML") + ko.utils.setHtml(this.domElement, valueToWrite); + else + this.domElement[elemContentsProperty] = valueToWrite; + } + }; + + ko.templateSources.domElement.prototype['data'] = function(key /*, valueToWrite */) { + if (arguments.length === 1) { + return ko.utils.domData.get(this.domElement, "templateSourceData_" + key); + } else { + ko.utils.domData.set(this.domElement, "templateSourceData_" + key, arguments[1]); + } + }; + + // ---- ko.templateSources.anonymousTemplate ----- + // Anonymous templates are normally saved/retrieved as DOM nodes through "nodes". + // For compatibility, you can also read "text"; it will be serialized from the nodes on demand. + // Writing to "text" is still supported, but then the template data will not be available as DOM nodes. + + var anonymousTemplatesDomDataKey = "__ko_anon_template__"; + ko.templateSources.anonymousTemplate = function(element) { + this.domElement = element; + } + ko.templateSources.anonymousTemplate.prototype = new ko.templateSources.domElement(); + ko.templateSources.anonymousTemplate.prototype['text'] = function(/* valueToWrite */) { + if (arguments.length == 0) { + var templateData = ko.utils.domData.get(this.domElement, anonymousTemplatesDomDataKey) || {}; + if (templateData.textData === undefined && templateData.containerData) + templateData.textData = templateData.containerData.innerHTML; + return templateData.textData; + } else { + var valueToWrite = arguments[0]; + ko.utils.domData.set(this.domElement, anonymousTemplatesDomDataKey, {textData: valueToWrite}); + } + }; + ko.templateSources.domElement.prototype['nodes'] = function(/* valueToWrite */) { + if (arguments.length == 0) { + var templateData = ko.utils.domData.get(this.domElement, anonymousTemplatesDomDataKey) || {}; + return templateData.containerData; + } else { + var valueToWrite = arguments[0]; + ko.utils.domData.set(this.domElement, anonymousTemplatesDomDataKey, {containerData: valueToWrite}); + } + }; + + ko.exportSymbol('templateSources', ko.templateSources); + ko.exportSymbol('templateSources.domElement', ko.templateSources.domElement); + ko.exportSymbol('templateSources.anonymousTemplate', ko.templateSources.anonymousTemplate); +})(); +(function () { + var _templateEngine; + ko.setTemplateEngine = function (templateEngine) { + if ((templateEngine != undefined) && !(templateEngine instanceof ko.templateEngine)) + throw new Error("templateEngine must inherit from ko.templateEngine"); + _templateEngine = templateEngine; + } + + function invokeForEachNodeOrCommentInContinuousRange(firstNode, lastNode, action) { + var node, nextInQueue = firstNode, firstOutOfRangeNode = ko.virtualElements.nextSibling(lastNode); + while (nextInQueue && ((node = nextInQueue) !== firstOutOfRangeNode)) { + nextInQueue = ko.virtualElements.nextSibling(node); + if (node.nodeType === 1 || node.nodeType === 8) + action(node); + } + } + + function activateBindingsOnContinuousNodeArray(continuousNodeArray, bindingContext) { + // To be used on any nodes that have been rendered by a template and have been inserted into some parent element + // Walks through continuousNodeArray (which *must* be continuous, i.e., an uninterrupted sequence of sibling nodes, because + // the algorithm for walking them relies on this), and for each top-level item in the virtual-element sense, + // (1) Does a regular "applyBindings" to associate bindingContext with this node and to activate any non-memoized bindings + // (2) Unmemoizes any memos in the DOM subtree (e.g., to activate bindings that had been memoized during template rewriting) + + if (continuousNodeArray.length) { + var firstNode = continuousNodeArray[0], lastNode = continuousNodeArray[continuousNodeArray.length - 1]; + + // Need to applyBindings *before* unmemoziation, because unmemoization might introduce extra nodes (that we don't want to re-bind) + // whereas a regular applyBindings won't introduce new memoized nodes + invokeForEachNodeOrCommentInContinuousRange(firstNode, lastNode, function(node) { + ko.applyBindings(bindingContext, node); + }); + invokeForEachNodeOrCommentInContinuousRange(firstNode, lastNode, function(node) { + ko.memoization.unmemoizeDomNodeAndDescendants(node, [bindingContext]); + }); + } + } + + function getFirstNodeFromPossibleArray(nodeOrNodeArray) { + return nodeOrNodeArray.nodeType ? nodeOrNodeArray + : nodeOrNodeArray.length > 0 ? nodeOrNodeArray[0] + : null; + } + + function executeTemplate(targetNodeOrNodeArray, renderMode, template, bindingContext, options) { + options = options || {}; + var firstTargetNode = targetNodeOrNodeArray && getFirstNodeFromPossibleArray(targetNodeOrNodeArray); + var templateDocument = firstTargetNode && firstTargetNode.ownerDocument; + var templateEngineToUse = (options['templateEngine'] || _templateEngine); + ko.templateRewriting.ensureTemplateIsRewritten(template, templateEngineToUse, templateDocument); + var renderedNodesArray = templateEngineToUse['renderTemplate'](template, bindingContext, options, templateDocument); + + // Loosely check result is an array of DOM nodes + if ((typeof renderedNodesArray.length != "number") || (renderedNodesArray.length > 0 && typeof renderedNodesArray[0].nodeType != "number")) + throw new Error("Template engine must return an array of DOM nodes"); + + var haveAddedNodesToParent = false; + switch (renderMode) { + case "replaceChildren": + ko.virtualElements.setDomNodeChildren(targetNodeOrNodeArray, renderedNodesArray); + haveAddedNodesToParent = true; + break; + case "replaceNode": + ko.utils.replaceDomNodes(targetNodeOrNodeArray, renderedNodesArray); + haveAddedNodesToParent = true; + break; + case "ignoreTargetNode": break; + default: + throw new Error("Unknown renderMode: " + renderMode); + } + + if (haveAddedNodesToParent) { + activateBindingsOnContinuousNodeArray(renderedNodesArray, bindingContext); + if (options['afterRender']) + ko.dependencyDetection.ignore(options['afterRender'], null, [renderedNodesArray, bindingContext['$data']]); + } + + return renderedNodesArray; + } + + ko.renderTemplate = function (template, dataOrBindingContext, options, targetNodeOrNodeArray, renderMode) { + options = options || {}; + if ((options['templateEngine'] || _templateEngine) == undefined) + throw new Error("Set a template engine before calling renderTemplate"); + renderMode = renderMode || "replaceChildren"; + + if (targetNodeOrNodeArray) { + var firstTargetNode = getFirstNodeFromPossibleArray(targetNodeOrNodeArray); + + var whenToDispose = function () { return (!firstTargetNode) || !ko.utils.domNodeIsAttachedToDocument(firstTargetNode); }; // Passive disposal (on next evaluation) + var activelyDisposeWhenNodeIsRemoved = (firstTargetNode && renderMode == "replaceNode") ? firstTargetNode.parentNode : firstTargetNode; + + return ko.dependentObservable( // So the DOM is automatically updated when any dependency changes + function () { + // Ensure we've got a proper binding context to work with + var bindingContext = (dataOrBindingContext && (dataOrBindingContext instanceof ko.bindingContext)) + ? dataOrBindingContext + : new ko.bindingContext(ko.utils.unwrapObservable(dataOrBindingContext)); + + // Support selecting template as a function of the data being rendered + var templateName = typeof(template) == 'function' ? template(bindingContext['$data'], bindingContext) : template; + + var renderedNodesArray = executeTemplate(targetNodeOrNodeArray, renderMode, templateName, bindingContext, options); + if (renderMode == "replaceNode") { + targetNodeOrNodeArray = renderedNodesArray; + firstTargetNode = getFirstNodeFromPossibleArray(targetNodeOrNodeArray); + } + }, + null, + { disposeWhen: whenToDispose, disposeWhenNodeIsRemoved: activelyDisposeWhenNodeIsRemoved } + ); + } else { + // We don't yet have a DOM node to evaluate, so use a memo and render the template later when there is a DOM node + return ko.memoization.memoize(function (domNode) { + ko.renderTemplate(template, dataOrBindingContext, options, domNode, "replaceNode"); + }); + } + }; + + ko.renderTemplateForEach = function (template, arrayOrObservableArray, options, targetNode, parentBindingContext) { + // Since setDomNodeChildrenFromArrayMapping always calls executeTemplateForArrayItem and then + // activateBindingsCallback for added items, we can store the binding context in the former to use in the latter. + var arrayItemContext; + + // This will be called by setDomNodeChildrenFromArrayMapping to get the nodes to add to targetNode + var executeTemplateForArrayItem = function (arrayValue, index) { + // Support selecting template as a function of the data being rendered + arrayItemContext = parentBindingContext['createChildContext'](ko.utils.unwrapObservable(arrayValue), options['as']); + arrayItemContext['$index'] = index; + var templateName = typeof(template) == 'function' ? template(arrayValue, arrayItemContext) : template; + return executeTemplate(null, "ignoreTargetNode", templateName, arrayItemContext, options); + } + + // This will be called whenever setDomNodeChildrenFromArrayMapping has added nodes to targetNode + var activateBindingsCallback = function(arrayValue, addedNodesArray, index) { + activateBindingsOnContinuousNodeArray(addedNodesArray, arrayItemContext); + if (options['afterRender']) + options['afterRender'](addedNodesArray, arrayValue); + }; + + return ko.dependentObservable(function () { + var unwrappedArray = ko.utils.unwrapObservable(arrayOrObservableArray) || []; + if (typeof unwrappedArray.length == "undefined") // Coerce single value into array + unwrappedArray = [unwrappedArray]; + + // Filter out any entries marked as destroyed + var filteredArray = ko.utils.arrayFilter(unwrappedArray, function(item) { + return options['includeDestroyed'] || item === undefined || item === null || !ko.utils.unwrapObservable(item['_destroy']); + }); + + // Call setDomNodeChildrenFromArrayMapping, ignoring any observables unwrapped within (most likely from a callback function). + // If the array items are observables, though, they will be unwrapped in executeTemplateForArrayItem and managed within setDomNodeChildrenFromArrayMapping. + ko.dependencyDetection.ignore(ko.utils.setDomNodeChildrenFromArrayMapping, null, [targetNode, filteredArray, executeTemplateForArrayItem, options, activateBindingsCallback]); + + }, null, { disposeWhenNodeIsRemoved: targetNode }); + }; + + var templateComputedDomDataKey = '__ko__templateComputedDomDataKey__'; + function disposeOldComputedAndStoreNewOne(element, newComputed) { + var oldComputed = ko.utils.domData.get(element, templateComputedDomDataKey); + if (oldComputed && (typeof(oldComputed.dispose) == 'function')) + oldComputed.dispose(); + ko.utils.domData.set(element, templateComputedDomDataKey, (newComputed && newComputed.isActive()) ? newComputed : undefined); + } + + ko.bindingHandlers['template'] = { + 'init': function(element, valueAccessor) { + // Support anonymous templates + var bindingValue = ko.utils.unwrapObservable(valueAccessor()); + if ((typeof bindingValue != "string") && (!bindingValue['name']) && (element.nodeType == 1 || element.nodeType == 8)) { + // It's an anonymous template - store the element contents, then clear the element + var templateNodes = element.nodeType == 1 ? element.childNodes : ko.virtualElements.childNodes(element), + container = ko.utils.moveCleanedNodesToContainerElement(templateNodes); // This also removes the nodes from their current parent + new ko.templateSources.anonymousTemplate(element)['nodes'](container); + } + return { 'controlsDescendantBindings': true }; + }, + 'update': function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { + var templateName = ko.utils.unwrapObservable(valueAccessor()), + options = {}, + shouldDisplay = true, + dataValue, + templateComputed = null; + + if (typeof templateName != "string") { + options = templateName; + templateName = options['name']; + + // Support "if"/"ifnot" conditions + if ('if' in options) + shouldDisplay = ko.utils.unwrapObservable(options['if']); + if (shouldDisplay && 'ifnot' in options) + shouldDisplay = !ko.utils.unwrapObservable(options['ifnot']); + + dataValue = ko.utils.unwrapObservable(options['data']); + } + + if ('foreach' in options) { + // Render once for each data point (treating data set as empty if shouldDisplay==false) + var dataArray = (shouldDisplay && options['foreach']) || []; + templateComputed = ko.renderTemplateForEach(templateName || element, dataArray, options, element, bindingContext); + } else if (!shouldDisplay) { + ko.virtualElements.emptyNode(element); + } else { + // Render once for this single data point (or use the viewModel if no data was provided) + var innerBindingContext = ('data' in options) ? + bindingContext['createChildContext'](dataValue, options['as']) : // Given an explitit 'data' value, we create a child binding context for it + bindingContext; // Given no explicit 'data' value, we retain the same binding context + templateComputed = ko.renderTemplate(templateName || element, innerBindingContext, options, element); + } + + // It only makes sense to have a single template computed per element (otherwise which one should have its output displayed?) + disposeOldComputedAndStoreNewOne(element, templateComputed); + } + }; + + // Anonymous templates can't be rewritten. Give a nice error message if you try to do it. + ko.expressionRewriting.bindingRewriteValidators['template'] = function(bindingValue) { + var parsedBindingValue = ko.expressionRewriting.parseObjectLiteral(bindingValue); + + if ((parsedBindingValue.length == 1) && parsedBindingValue[0]['unknown']) + return null; // It looks like a string literal, not an object literal, so treat it as a named template (which is allowed for rewriting) + + if (ko.expressionRewriting.keyValueArrayContainsKey(parsedBindingValue, "name")) + return null; // Named templates can be rewritten, so return "no error" + return "This template engine does not support anonymous templates nested within its templates"; + }; + + ko.virtualElements.allowedBindings['template'] = true; +})(); + +ko.exportSymbol('setTemplateEngine', ko.setTemplateEngine); +ko.exportSymbol('renderTemplate', ko.renderTemplate); + +ko.utils.compareArrays = (function () { + var statusNotInOld = 'added', statusNotInNew = 'deleted'; + + // Simple calculation based on Levenshtein distance. + function compareArrays(oldArray, newArray, dontLimitMoves) { + oldArray = oldArray || []; + newArray = newArray || []; + + if (oldArray.length <= newArray.length) + return compareSmallArrayToBigArray(oldArray, newArray, statusNotInOld, statusNotInNew, dontLimitMoves); + else + return compareSmallArrayToBigArray(newArray, oldArray, statusNotInNew, statusNotInOld, dontLimitMoves); + } + + function compareSmallArrayToBigArray(smlArray, bigArray, statusNotInSml, statusNotInBig, dontLimitMoves) { + var myMin = Math.min, + myMax = Math.max, + editDistanceMatrix = [], + smlIndex, smlIndexMax = smlArray.length, + bigIndex, bigIndexMax = bigArray.length, + compareRange = (bigIndexMax - smlIndexMax) || 1, + maxDistance = smlIndexMax + bigIndexMax + 1, + thisRow, lastRow, + bigIndexMaxForRow, bigIndexMinForRow; + + for (smlIndex = 0; smlIndex <= smlIndexMax; smlIndex++) { + lastRow = thisRow; + editDistanceMatrix.push(thisRow = []); + bigIndexMaxForRow = myMin(bigIndexMax, smlIndex + compareRange); + bigIndexMinForRow = myMax(0, smlIndex - 1); + for (bigIndex = bigIndexMinForRow; bigIndex <= bigIndexMaxForRow; bigIndex++) { + if (!bigIndex) + thisRow[bigIndex] = smlIndex + 1; + else if (!smlIndex) // Top row - transform empty array into new array via additions + thisRow[bigIndex] = bigIndex + 1; + else if (smlArray[smlIndex - 1] === bigArray[bigIndex - 1]) + thisRow[bigIndex] = lastRow[bigIndex - 1]; // copy value (no edit) + else { + var northDistance = lastRow[bigIndex] || maxDistance; // not in big (deletion) + var westDistance = thisRow[bigIndex - 1] || maxDistance; // not in small (addition) + thisRow[bigIndex] = myMin(northDistance, westDistance) + 1; + } + } + } + + var editScript = [], meMinusOne, notInSml = [], notInBig = []; + for (smlIndex = smlIndexMax, bigIndex = bigIndexMax; smlIndex || bigIndex;) { + meMinusOne = editDistanceMatrix[smlIndex][bigIndex] - 1; + if (bigIndex && meMinusOne === editDistanceMatrix[smlIndex][bigIndex-1]) { + notInSml.push(editScript[editScript.length] = { // added + 'status': statusNotInSml, + 'value': bigArray[--bigIndex], + 'index': bigIndex }); + } else if (smlIndex && meMinusOne === editDistanceMatrix[smlIndex - 1][bigIndex]) { + notInBig.push(editScript[editScript.length] = { // deleted + 'status': statusNotInBig, + 'value': smlArray[--smlIndex], + 'index': smlIndex }); + } else { + editScript.push({ + 'status': "retained", + 'value': bigArray[--bigIndex] }); + --smlIndex; + } + } + + if (notInSml.length && notInBig.length) { + // Set a limit on the number of consecutive non-matching comparisons; having it a multiple of + // smlIndexMax keeps the time complexity of this algorithm linear. + var limitFailedCompares = smlIndexMax * 10, failedCompares, + a, d, notInSmlItem, notInBigItem; + // Go through the items that have been added and deleted and try to find matches between them. + for (failedCompares = a = 0; (dontLimitMoves || failedCompares < limitFailedCompares) && (notInSmlItem = notInSml[a]); a++) { + for (d = 0; notInBigItem = notInBig[d]; d++) { + if (notInSmlItem['value'] === notInBigItem['value']) { + notInSmlItem['moved'] = notInBigItem['index']; + notInBigItem['moved'] = notInSmlItem['index']; + notInBig.splice(d,1); // This item is marked as moved; so remove it from notInBig list + failedCompares = d = 0; // Reset failed compares count because we're checking for consecutive failures + break; + } + } + failedCompares += d; + } + } + return editScript.reverse(); + } + + return compareArrays; +})(); + +ko.exportSymbol('utils.compareArrays', ko.utils.compareArrays); + +(function () { + // Objective: + // * Given an input array, a container DOM node, and a function from array elements to arrays of DOM nodes, + // map the array elements to arrays of DOM nodes, concatenate together all these arrays, and use them to populate the container DOM node + // * Next time we're given the same combination of things (with the array possibly having mutated), update the container DOM node + // so that its children is again the concatenation of the mappings of the array elements, but don't re-map any array elements that we + // previously mapped - retain those nodes, and just insert/delete other ones + + // "callbackAfterAddingNodes" will be invoked after any "mapping"-generated nodes are inserted into the container node + // You can use this, for example, to activate bindings on those nodes. + + function fixUpNodesToBeMovedOrRemoved(contiguousNodeArray) { + // Before moving, deleting, or replacing a set of nodes that were previously outputted by the "map" function, we have to reconcile + // them against what is in the DOM right now. It may be that some of the nodes have already been removed from the document, + // or that new nodes might have been inserted in the middle, for example by a binding. Also, there may previously have been + // leading comment nodes (created by rewritten string-based templates) that have since been removed during binding. + // So, this function translates the old "map" output array into its best guess of what set of current DOM nodes should be removed. + // + // Rules: + // [A] Any leading nodes that aren't in the document any more should be ignored + // These most likely correspond to memoization nodes that were already removed during binding + // See https://github.com/SteveSanderson/knockout/pull/440 + // [B] We want to output a contiguous series of nodes that are still in the document. So, ignore any nodes that + // have already been removed, and include any nodes that have been inserted among the previous collection + + // Rule [A] + while (contiguousNodeArray.length && !ko.utils.domNodeIsAttachedToDocument(contiguousNodeArray[0])) + contiguousNodeArray.splice(0, 1); + + // Rule [B] + if (contiguousNodeArray.length > 1) { + // Build up the actual new contiguous node set + var current = contiguousNodeArray[0], last = contiguousNodeArray[contiguousNodeArray.length - 1], newContiguousSet = [current]; + while (current !== last) { + current = current.nextSibling; + if (!current) // Won't happen, except if the developer has manually removed some DOM elements (then we're in an undefined scenario) + return; + newContiguousSet.push(current); + } + + // ... then mutate the input array to match this. + // (The following line replaces the contents of contiguousNodeArray with newContiguousSet) + Array.prototype.splice.apply(contiguousNodeArray, [0, contiguousNodeArray.length].concat(newContiguousSet)); + } + return contiguousNodeArray; + } + + function mapNodeAndRefreshWhenChanged(containerNode, mapping, valueToMap, callbackAfterAddingNodes, index) { + // Map this array value inside a dependentObservable so we re-map when any dependency changes + var mappedNodes = []; + var dependentObservable = ko.dependentObservable(function() { + var newMappedNodes = mapping(valueToMap, index) || []; + + // On subsequent evaluations, just replace the previously-inserted DOM nodes + if (mappedNodes.length > 0) { + ko.utils.replaceDomNodes(fixUpNodesToBeMovedOrRemoved(mappedNodes), newMappedNodes); + if (callbackAfterAddingNodes) + ko.dependencyDetection.ignore(callbackAfterAddingNodes, null, [valueToMap, newMappedNodes, index]); + } + + // Replace the contents of the mappedNodes array, thereby updating the record + // of which nodes would be deleted if valueToMap was itself later removed + mappedNodes.splice(0, mappedNodes.length); + ko.utils.arrayPushAll(mappedNodes, newMappedNodes); + }, null, { disposeWhenNodeIsRemoved: containerNode, disposeWhen: function() { return (mappedNodes.length == 0) || !ko.utils.domNodeIsAttachedToDocument(mappedNodes[0]) } }); + return { mappedNodes : mappedNodes, dependentObservable : (dependentObservable.isActive() ? dependentObservable : undefined) }; + } + + var lastMappingResultDomDataKey = "setDomNodeChildrenFromArrayMapping_lastMappingResult"; + + ko.utils.setDomNodeChildrenFromArrayMapping = function (domNode, array, mapping, options, callbackAfterAddingNodes) { + // Compare the provided array against the previous one + array = array || []; + options = options || {}; + var isFirstExecution = ko.utils.domData.get(domNode, lastMappingResultDomDataKey) === undefined; + var lastMappingResult = ko.utils.domData.get(domNode, lastMappingResultDomDataKey) || []; + var lastArray = ko.utils.arrayMap(lastMappingResult, function (x) { return x.arrayEntry; }); + var editScript = ko.utils.compareArrays(lastArray, array); + + // Build the new mapping result + var newMappingResult = []; + var lastMappingResultIndex = 0; + var newMappingResultIndex = 0; + + var nodesToDelete = []; + var itemsToProcess = []; + var itemsForBeforeRemoveCallbacks = []; + var itemsForMoveCallbacks = []; + var itemsForAfterAddCallbacks = []; + var mapData; + + function itemMovedOrRetained(editScriptIndex, oldPosition) { + mapData = lastMappingResult[oldPosition]; + if (newMappingResultIndex !== oldPosition) + itemsForMoveCallbacks[editScriptIndex] = mapData; + // Since updating the index might change the nodes, do so before calling fixUpNodesToBeMovedOrRemoved + mapData.indexObservable(newMappingResultIndex++); + fixUpNodesToBeMovedOrRemoved(mapData.mappedNodes); + newMappingResult.push(mapData); + itemsToProcess.push(mapData); + } + + function callCallback(callback, items) { + if (callback) { + for (var i = 0, n = items.length; i < n; i++) { + if (items[i]) { + ko.utils.arrayForEach(items[i].mappedNodes, function(node) { + callback(node, i, items[i].arrayEntry); + }); + } + } + } + } + + for (var i = 0, editScriptItem, movedIndex; editScriptItem = editScript[i]; i++) { + movedIndex = editScriptItem['moved']; + switch (editScriptItem['status']) { + case "deleted": + if (movedIndex === undefined) { + mapData = lastMappingResult[lastMappingResultIndex]; + + // Stop tracking changes to the mapping for these nodes + if (mapData.dependentObservable) + mapData.dependentObservable.dispose(); + + // Queue these nodes for later removal + nodesToDelete.push.apply(nodesToDelete, fixUpNodesToBeMovedOrRemoved(mapData.mappedNodes)); + if (options['beforeRemove']) { + itemsForBeforeRemoveCallbacks[i] = mapData; + itemsToProcess.push(mapData); + } + } + lastMappingResultIndex++; + break; + + case "retained": + itemMovedOrRetained(i, lastMappingResultIndex++); + break; + + case "added": + if (movedIndex !== undefined) { + itemMovedOrRetained(i, movedIndex); + } else { + mapData = { arrayEntry: editScriptItem['value'], indexObservable: ko.observable(newMappingResultIndex++) }; + newMappingResult.push(mapData); + itemsToProcess.push(mapData); + if (!isFirstExecution) + itemsForAfterAddCallbacks[i] = mapData; + } + break; + } + } + + // Call beforeMove first before any changes have been made to the DOM + callCallback(options['beforeMove'], itemsForMoveCallbacks); + + // Next remove nodes for deleted items (or just clean if there's a beforeRemove callback) + ko.utils.arrayForEach(nodesToDelete, options['beforeRemove'] ? ko.cleanNode : ko.removeNode); + + // Next add/reorder the remaining items (will include deleted items if there's a beforeRemove callback) + for (var i = 0, nextNode = ko.virtualElements.firstChild(domNode), lastNode, node; mapData = itemsToProcess[i]; i++) { + // Get nodes for newly added items + if (!mapData.mappedNodes) + ko.utils.extend(mapData, mapNodeAndRefreshWhenChanged(domNode, mapping, mapData.arrayEntry, callbackAfterAddingNodes, mapData.indexObservable)); + + // Put nodes in the right place if they aren't there already + for (var j = 0; node = mapData.mappedNodes[j]; nextNode = node.nextSibling, lastNode = node, j++) { + if (node !== nextNode) + ko.virtualElements.insertAfter(domNode, node, lastNode); + } + + // Run the callbacks for newly added nodes (for example, to apply bindings, etc.) + if (!mapData.initialized && callbackAfterAddingNodes) { + callbackAfterAddingNodes(mapData.arrayEntry, mapData.mappedNodes, mapData.indexObservable); + mapData.initialized = true; + } + } + + // If there's a beforeRemove callback, call it after reordering. + // Note that we assume that the beforeRemove callback will usually be used to remove the nodes using + // some sort of animation, which is why we first reorder the nodes that will be removed. If the + // callback instead removes the nodes right away, it would be more efficient to skip reordering them. + // Perhaps we'll make that change in the future if this scenario becomes more common. + callCallback(options['beforeRemove'], itemsForBeforeRemoveCallbacks); + + // Finally call afterMove and afterAdd callbacks + callCallback(options['afterMove'], itemsForMoveCallbacks); + callCallback(options['afterAdd'], itemsForAfterAddCallbacks); + + // Store a copy of the array items we just considered so we can difference it next time + ko.utils.domData.set(domNode, lastMappingResultDomDataKey, newMappingResult); + } +})(); + +ko.exportSymbol('utils.setDomNodeChildrenFromArrayMapping', ko.utils.setDomNodeChildrenFromArrayMapping); +ko.nativeTemplateEngine = function () { + this['allowTemplateRewriting'] = false; +} + +ko.nativeTemplateEngine.prototype = new ko.templateEngine(); +ko.nativeTemplateEngine.prototype['renderTemplateSource'] = function (templateSource, bindingContext, options) { + var useNodesIfAvailable = !(ko.utils.ieVersion < 9), // IE<9 cloneNode doesn't work properly + templateNodesFunc = useNodesIfAvailable ? templateSource['nodes'] : null, + templateNodes = templateNodesFunc ? templateSource['nodes']() : null; + + if (templateNodes) { + return ko.utils.makeArray(templateNodes.cloneNode(true).childNodes); + } else { + var templateText = templateSource['text'](); + return ko.utils.parseHtmlFragment(templateText); + } +}; + +ko.nativeTemplateEngine.instance = new ko.nativeTemplateEngine(); +ko.setTemplateEngine(ko.nativeTemplateEngine.instance); + +ko.exportSymbol('nativeTemplateEngine', ko.nativeTemplateEngine); +(function() { + ko.jqueryTmplTemplateEngine = function () { + // Detect which version of jquery-tmpl you're using. Unfortunately jquery-tmpl + // doesn't expose a version number, so we have to infer it. + // Note that as of Knockout 1.3, we only support jQuery.tmpl 1.0.0pre and later, + // which KO internally refers to as version "2", so older versions are no longer detected. + var jQueryTmplVersion = this.jQueryTmplVersion = (function() { + if ((typeof(jQuery) == "undefined") || !(jQuery['tmpl'])) + return 0; + // Since it exposes no official version number, we use our own numbering system. To be updated as jquery-tmpl evolves. + try { + if (jQuery['tmpl']['tag']['tmpl']['open'].toString().indexOf('__') >= 0) { + // Since 1.0.0pre, custom tags should append markup to an array called "__" + return 2; // Final version of jquery.tmpl + } + } catch(ex) { /* Apparently not the version we were looking for */ } + + return 1; // Any older version that we don't support + })(); + + function ensureHasReferencedJQueryTemplates() { + if (jQueryTmplVersion < 2) + throw new Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later."); + } + + function executeTemplate(compiledTemplate, data, jQueryTemplateOptions) { + return jQuery['tmpl'](compiledTemplate, data, jQueryTemplateOptions); + } + + this['renderTemplateSource'] = function(templateSource, bindingContext, options) { + options = options || {}; + ensureHasReferencedJQueryTemplates(); + + // Ensure we have stored a precompiled version of this template (don't want to reparse on every render) + var precompiled = templateSource['data']('precompiled'); + if (!precompiled) { + var templateText = templateSource['text']() || ""; + // Wrap in "with($whatever.koBindingContext) { ... }" + templateText = "{{ko_with $item.koBindingContext}}" + templateText + "{{/ko_with}}"; + + precompiled = jQuery['template'](null, templateText); + templateSource['data']('precompiled', precompiled); + } + + var data = [bindingContext['$data']]; // Prewrap the data in an array to stop jquery.tmpl from trying to unwrap any arrays + var jQueryTemplateOptions = jQuery['extend']({ 'koBindingContext': bindingContext }, options['templateOptions']); + + var resultNodes = executeTemplate(precompiled, data, jQueryTemplateOptions); + resultNodes['appendTo'](document.createElement("div")); // Using "appendTo" forces jQuery/jQuery.tmpl to perform necessary cleanup work + + jQuery['fragments'] = {}; // Clear jQuery's fragment cache to avoid a memory leak after a large number of template renders + return resultNodes; + }; + + this['createJavaScriptEvaluatorBlock'] = function(script) { + return "{{ko_code ((function() { return " + script + " })()) }}"; + }; + + this['addTemplate'] = function(templateName, templateMarkup) { + document.write("<script type='text/html' id='" + templateName + "'>" + templateMarkup + "</script>"); + }; + + if (jQueryTmplVersion > 0) { + jQuery['tmpl']['tag']['ko_code'] = { + open: "__.push($1 || '');" + }; + jQuery['tmpl']['tag']['ko_with'] = { + open: "with($1) {", + close: "} " + }; + } + }; + + ko.jqueryTmplTemplateEngine.prototype = new ko.templateEngine(); + + // Use this one by default *only if jquery.tmpl is referenced* + var jqueryTmplTemplateEngineInstance = new ko.jqueryTmplTemplateEngine(); + if (jqueryTmplTemplateEngineInstance.jQueryTmplVersion > 0) + ko.setTemplateEngine(jqueryTmplTemplateEngineInstance); + + ko.exportSymbol('jqueryTmplTemplateEngine', ko.jqueryTmplTemplateEngine); +})(); +}); +})(window,document,navigator,window["jQuery"]); +})(); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/knockout-sortable.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/knockout-sortable.js new file mode 100644 index 000000000..f4259528b --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/knockout-sortable.js @@ -0,0 +1,285 @@ +//knockout-sortable 0.6.6 | (c) 2012 Ryan Niemeyer | http://www.opensource.org/licenses/mit-license +(function(factory) { + if (typeof define === "function" && define.amd) { + // AMD anonymous module + define(["knockout", "jquery", "jquery.ui"], factory); + } else { + // No module loader (plain <script> tag) - put directly in global namespace + factory(window.ko, jQuery); + } +})(function(ko, $, undefined) { + var ITEMKEY = "ko_sortItem", + LISTKEY = "ko_sortList", + PARENTKEY = "ko_parentList", + DRAGKEY = "ko_dragItem"; + + //internal afterRender that adds meta-data to children + var addMetaDataAfterRender = function(elements, data) { + ko.utils.arrayForEach(elements, function(element) { + if (element.nodeType === 1) { + ko.utils.domData.set(element, ITEMKEY, data); + ko.utils.domData.set(element, PARENTKEY, ko.utils.domData.get(element.parentNode, LISTKEY)); + } + }); + }; + + //prepare the proper options for the template binding + var prepareTemplateOptions = function(valueAccessor, dataName) { + var result = {}, + options = ko.utils.unwrapObservable(valueAccessor()), + actualAfterRender; + + //build our options to pass to the template engine + if (options.data) { + result[dataName] = options.data; + result.name = options.template; + } else { + result[dataName] = valueAccessor(); + } + + ko.utils.arrayForEach(["afterAdd", "afterRender", "beforeRemove", "includeDestroyed", "templateEngine", "templateOptions"], function (option) { + result[option] = options[option] || ko.bindingHandlers.sortable[option]; + }); + + //use an afterRender function to add meta-data + if (dataName === "foreach") { + if (result.afterRender) { + //wrap the existing function, if it was passed + actualAfterRender = result.afterRender; + result.afterRender = function(element, data) { + addMetaDataAfterRender.call(data, element, data); + actualAfterRender.call(data, element, data); + }; + } else { + result.afterRender = addMetaDataAfterRender; + } + } + + //return options to pass to the template binding + return result; + }; + + //connect items with observableArrays + ko.bindingHandlers.sortable = { + init: function(element, valueAccessor, allBindingsAccessor, data, context) { + var $element = $(element), + value = ko.utils.unwrapObservable(valueAccessor()) || {}, + templateOptions = prepareTemplateOptions(valueAccessor, "foreach"), + sortable = {}, + startActual, updateActual; + + //remove leading/trailing text nodes from anonymous templates + ko.utils.arrayForEach(element.childNodes, function(node) { + if (node && node.nodeType === 3) { + node.parentNode.removeChild(node); + } + }); + + //build a new object that has the global options with overrides from the binding + $.extend(true, sortable, ko.bindingHandlers.sortable); + if (value.options && sortable.options) { + ko.utils.extend(sortable.options, value.options); + delete value.options; + } + ko.utils.extend(sortable, value); + + //if allowDrop is an observable or a function, then execute it in a computed observable + if (sortable.connectClass && (ko.isObservable(sortable.allowDrop) || typeof sortable.allowDrop == "function")) { + ko.computed({ + read: function() { + var value = ko.utils.unwrapObservable(sortable.allowDrop), + shouldAdd = typeof value == "function" ? value.call(this, templateOptions.foreach) : value; + ko.utils.toggleDomNodeCssClass(element, sortable.connectClass, shouldAdd); + }, + disposeWhenNodeIsRemoved: element + }, this); + } else { + ko.utils.toggleDomNodeCssClass(element, sortable.connectClass, sortable.allowDrop); + } + + //wrap the template binding + ko.bindingHandlers.template.init(element, function() { return templateOptions; }, allBindingsAccessor, data, context); + + //keep a reference to start/update functions that might have been passed in + startActual = sortable.options.start; + updateActual = sortable.options.update; + + //initialize sortable binding after template binding has rendered in update function + setTimeout(function() { + var dragItem; + $element.sortable(ko.utils.extend(sortable.options, { + start: function(event, ui) { + //make sure that fields have a chance to update model + ui.item.find("input:focus").change(); + if (startActual) { + startActual.apply(this, arguments); + } + }, + receive: function(event, ui) { + dragItem = ko.utils.domData.get(ui.item[0], DRAGKEY); + if (dragItem && dragItem.clone) { + dragItem = dragItem.clone(); + } + }, + update: function(event, ui) { + var sourceParent, targetParent, targetIndex, i, targetUnwrapped, arg, + el = ui.item[0], + item = ko.utils.domData.get(el, ITEMKEY) || dragItem; + + dragItem = null; + + if (this === ui.item.parent()[0] && item) { + //identify parents + sourceParent = ko.utils.domData.get(el, PARENTKEY); + targetParent = ko.utils.domData.get(el.parentNode, LISTKEY); + targetIndex = ko.utils.arrayIndexOf(ui.item.parent().children(), el); + + //take destroyed items into consideration + if (!templateOptions.includeDestroyed) { + if(targetParent){ + targetUnwrapped = $.isFunction(targetParent)?targetParent():targetParent; + for (i = 0; i < targetIndex; i++) { + //add one for every destroyed item we find before the targetIndex in the target array + if (targetUnwrapped[i] && targetUnwrapped[i]._destroy) { + targetIndex++; + } + } + } + } + + if (sortable.beforeMove || sortable.afterMove) { + arg = { + item: item, + sourceParent: sourceParent, + sourceParentNode: sourceParent && el.parentNode, + sourceIndex: sourceParent && sourceParent.indexOf(item), + targetParent: targetParent, + targetIndex: targetIndex, + cancelDrop: false + }; + } + + if (sortable.beforeMove) { + sortable.beforeMove.call(this, arg, event, ui); + if (arg.cancelDrop) { + //call cancel on the correct list + if (arg.sourceParent) { + $(arg.sourceParent === arg.targetParent ? this : ui.sender).sortable('cancel'); + } + //for a draggable item just remove the element + else { + $(el).remove(); + } + + return; + } + } + + if (targetIndex >= 0) { + if (sourceParent) { + if( $.isFunction(sourceParent.remove)) sourceParent.remove(item); + } + + targetParent.splice(targetIndex, 0, item); + } + + //rendering is handled by manipulating the observableArray; ignore dropped element + ko.utils.domData.set(el, ITEMKEY, null); + ui.item.remove(); + + //allow binding to accept a function to execute after moving the item + if (sortable.afterMove) { + sortable.afterMove.call(this, arg, event, ui); + } + } + + if (updateActual) { + updateActual.apply(this, arguments); + } + }, + connectWith: sortable.connectClass ? "." + sortable.connectClass : false + })); + + //handle enabling/disabling sorting + if (sortable.isEnabled !== undefined) { + ko.computed({ + read: function() { + $element.sortable(ko.utils.unwrapObservable(sortable.isEnabled) ? "enable" : "disable"); + }, + disposeWhenNodeIsRemoved: element + }); + } + }, 0); + + //handle disposal + ko.utils.domNodeDisposal.addDisposeCallback(element, function() { + $element.sortable("destroy"); + }); + + return { 'controlsDescendantBindings': true }; + }, + update: function(element, valueAccessor, allBindingsAccessor, data, context) { + var templateOptions = prepareTemplateOptions(valueAccessor, "foreach"); + + //attach meta-data + ko.utils.domData.set(element, LISTKEY, templateOptions.foreach); + + //call template binding's update with correct options + ko.bindingHandlers.template.update(element, function() { return templateOptions; }, allBindingsAccessor, data, context); + }, + connectClass: 'ko_container', + allowDrop: true, + afterMove: null, + beforeMove: null, + options: {} + }; + + //create a draggable that is appropriate for dropping into a sortable + ko.bindingHandlers.draggable = { + init: function(element, valueAccessor, allBindingsAccessor, data, context) { + var value = ko.utils.unwrapObservable(valueAccessor()) || {}, + options = value.options || {}, + draggableOptions = ko.utils.extend({}, ko.bindingHandlers.draggable.options), + templateOptions = prepareTemplateOptions(valueAccessor, "data"), + connectClass = value.connectClass || ko.bindingHandlers.draggable.connectClass, + isEnabled = value.isEnabled !== undefined ? value.isEnabled : ko.bindingHandlers.draggable.isEnabled; + + value = value.data || value; + + //set meta-data + ko.utils.domData.set(element, DRAGKEY, value); + + //override global options with override options passed in + ko.utils.extend(draggableOptions, options); + + //setup connection to a sortable + + draggableOptions.connectToSortable = connectClass ? "." + connectClass : false; + + //initialize draggable + $(element).draggable(draggableOptions); + + //handle enabling/disabling sorting + if (isEnabled !== undefined) { + ko.computed({ + read: function() { + $(element).draggable(ko.utils.unwrapObservable(isEnabled) ? "enable" : "disable"); + }, + disposeWhenNodeIsRemoved: element + }); + } + + return ko.bindingHandlers.template.init(element, function() { return templateOptions; }, allBindingsAccessor, data, context); + }, + update: function(element, valueAccessor, allBindingsAccessor, data, context) { + var templateOptions = prepareTemplateOptions(valueAccessor, "data"); + + return ko.bindingHandlers.template.update(element, function() { return templateOptions; }, allBindingsAccessor, data, context); + }, + connectClass: ko.bindingHandlers.sortable.connectClass, + options: { + helper: "clone" + } + }; + +}); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/knockout.simpleGrid.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/knockout.simpleGrid.js new file mode 100644 index 000000000..f9fbafc23 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/knockout.simpleGrid.js @@ -0,0 +1,86 @@ +// This is an example of one possible way to make a reusable component (or 'plugin'), consisting of: +// * A view model class, which gives a way to configure the component and to interact with it (e.g., by exposing currentPageIndex as an observable, external code can change the page index) +// * A custom binding (ko.bindingHandlers.simpleGrid in this example) so a developer can place instances of it into the DOM +// - in this example, the custom binding works by rendering some predefined templates using the ko.jqueryTmplTemplateEngine template engine +// +// There are loads of ways this grid example could be expanded. For example, +// * Letting the developer override the templates used to create the table header, table body, and page links div +// * Adding a "sort by clicking column headers" option +// * Creating some API to fetch table data using Ajax requests +// ... etc + + + +(function(factory) { + if (typeof define === "function" && define.amd) { + // AMD anonymous module + define("knockout.simpleGrid",["jquery","knockout","utils","i18n"], factory); + } else { + // No module loader (plain <script> tag) - put directly in global namespace + factory(window.ko, jQuery); + } +})(function ($,ko,utils,i18n) { + + + ko.simpleGrid = { + // Defines a view model class you can use to populate a grid + viewModel: function (configuration) { + this.data = configuration.data; + this.currentPageIndex = ko.observable(0); + this.pageSize = configuration.pageSize || 5; + this.columns = configuration.columns; + + this.itemsOnCurrentPage = ko.computed(function () { + var startIndex = this.pageSize * this.currentPageIndex(); + return this.data.slice(startIndex, startIndex + this.pageSize); + }, this); + + this.maxPageIndex = ko.computed(function () { + return Math.ceil(ko.utils.unwrapObservable(this.data).length / this.pageSize); + }, this); + this.i18n=function(key){ + return $.i18n.prop(key); + }; + this.gridUpdateCallBack = configuration.gridUpdateCallBack; + this.pageLinksUpdateCallBack = configuration.pageLinksUpdateCallBack; + + } + }; + + // Templates used to render the grid + var templateEngine = new ko.jqueryTmplTemplateEngine(); + + + // The "simpleGrid" binding + ko.bindingHandlers.simpleGrid = { + // This method is called to initialize the node, and will also be called again if you change what the grid is bound to + update: function (element, viewModelAccessor, allBindingsAccessor) { + var viewModel = viewModelAccessor(), allBindings = allBindingsAccessor(); + + // Empty the element + while(element.firstChild) { + ko.removeNode(element.firstChild); + } + + // Allow the default templates to be overridden + var gridTemplateName = allBindings.simpleGridTemplate || "ko_usersGrid_grid", + pageLinksTemplateName = allBindings.simpleGridPagerTemplate || "ko_simpleGrid_pageLinks"; + + // Render the main grid + var gridContainer = element.appendChild(document.createElement("DIV")); + ko.renderTemplate(gridTemplateName, viewModel, { templateEngine: templateEngine }, gridContainer, "replaceNode") + .subscribe(viewModel.gridUpdateCallBack?viewModel.gridUpdateCallBack:function(){}); + + if (viewModel.gridUpdateCallBack) viewModel.gridUpdateCallBack(); + + // Render the page links + var pageLinksContainer = $("#"+allBindings.pageLinksId).get(0); + var renderedTemplate = ko.renderTemplate(pageLinksTemplateName, viewModel, { templateEngine: templateEngine }, pageLinksContainer, "replaceNode"); + if (renderedTemplate.subscribe){ + renderedTemplate.subscribe(viewModel.pageLinksUpdateCallBack?viewModel.pageLinksUpdateCallBack:function(){}); + } + if (viewModel.pageLinksUpdateCallBack) viewModel.pageLinksUpdateCallBack(); + } + }; +}) + diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/order.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/order.js new file mode 100644 index 000000000..5edd5ce03 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/order.js @@ -0,0 +1,189 @@ +/** + * @license RequireJS order 1.0.5 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved. + * Available via the MIT or new BSD license. + * see: http://github.com/jrburke/requirejs for details + */ +/*jslint nomen: false, plusplus: false, strict: false */ +/*global require: false, define: false, window: false, document: false, + setTimeout: false */ + +//Specify that requirejs optimizer should wrap this code in a closure that +//maps the namespaced requirejs API to non-namespaced local variables. +/*requirejs namespace: true */ + +(function () { + + //Sadly necessary browser inference due to differences in the way + //that browsers load and execute dynamically inserted javascript + //and whether the script/cache method works when ordered execution is + //desired. Currently, Gecko and Opera do not load/fire onload for scripts with + //type="script/cache" but they execute injected scripts in order + //unless the 'async' flag is present. + //However, this is all changing in latest browsers implementing HTML5 + //spec. With compliant browsers .async true by default, and + //if false, then it will execute in order. Favor that test first for forward + //compatibility. + var testScript = typeof document !== "undefined" && + typeof window !== "undefined" && + document.createElement("script"), + + supportsInOrderExecution = testScript && (testScript.async || + ((window.opera && + Object.prototype.toString.call(window.opera) === "[object Opera]") || + //If Firefox 2 does not have to be supported, then + //a better check may be: + //('mozIsLocallyAvailable' in window.navigator) + ("MozAppearance" in document.documentElement.style))), + + //This test is true for IE browsers, which will load scripts but only + //execute them once the script is added to the DOM. + supportsLoadSeparateFromExecute = testScript && + testScript.readyState === 'uninitialized', + + readyRegExp = /^(complete|loaded)$/, + cacheWaiting = [], + cached = {}, + scriptNodes = {}, + scriptWaiting = []; + + //Done with the test script. + testScript = null; + + //Callback used by the type="script/cache" callback that indicates a script + //has finished downloading. + function scriptCacheCallback(evt) { + var node = evt.currentTarget || evt.srcElement, i, + moduleName, resource; + + if (evt.type === "load" || readyRegExp.test(node.readyState)) { + //Pull out the name of the module and the context. + moduleName = node.getAttribute("data-requiremodule"); + + //Mark this cache request as loaded + cached[moduleName] = true; + + //Find out how many ordered modules have loaded + for (i = 0; (resource = cacheWaiting[i]); i++) { + if (cached[resource.name]) { + resource.req([resource.name], resource.onLoad); + } else { + //Something in the ordered list is not loaded, + //so wait. + break; + } + } + + //If just loaded some items, remove them from cacheWaiting. + if (i > 0) { + cacheWaiting.splice(0, i); + } + + //Remove this script tag from the DOM + //Use a setTimeout for cleanup because some older IE versions vomit + //if removing a script node while it is being evaluated. + setTimeout(function () { + node.parentNode.removeChild(node); + }, 15); + } + } + + /** + * Used for the IE case, where fetching is done by creating script element + * but not attaching it to the DOM. This function will be called when that + * happens so it can be determined when the node can be attached to the + * DOM to trigger its execution. + */ + function onFetchOnly(node) { + var i, loadedNode, resourceName; + + //Mark this script as loaded. + node.setAttribute('data-orderloaded', 'loaded'); + + //Cycle through waiting scripts. If the matching node for them + //is loaded, and is in the right order, add it to the DOM + //to execute the script. + for (i = 0; (resourceName = scriptWaiting[i]); i++) { + loadedNode = scriptNodes[resourceName]; + if (loadedNode && + loadedNode.getAttribute('data-orderloaded') === 'loaded') { + delete scriptNodes[resourceName]; + require.addScriptToDom(loadedNode); + } else { + break; + } + } + + //If just loaded some items, remove them from waiting. + if (i > 0) { + scriptWaiting.splice(0, i); + } + } + + define({ + version: '1.0.5', + + load: function (name, req, onLoad, config) { + var hasToUrl = !!req.nameToUrl, + url, node, context; + + //If no nameToUrl, then probably a build with a loader that + //does not support it, and all modules are inlined. + if (!hasToUrl) { + req([name], onLoad); + return; + } + + url = req.nameToUrl(name, null); + + //Make sure the async attribute is not set for any pathway involving + //this script. + require.s.skipAsync[url] = true; + if (supportsInOrderExecution || config.isBuild) { + //Just a normal script tag append, but without async attribute + //on the script. + req([name], onLoad); + } else if (supportsLoadSeparateFromExecute) { + //Just fetch the URL, but do not execute it yet. The + //non-standards IE case. Really not so nice because it is + //assuming and touching requrejs internals. OK though since + //ordered execution should go away after a long while. + context = require.s.contexts._; + + if (!context.urlFetched[url] && !context.loaded[name]) { + //Indicate the script is being fetched. + context.urlFetched[url] = true; + + //Stuff from require.load + require.resourcesReady(false); + context.scriptCount += 1; + + //Fetch the script now, remember it. + node = require.attach(url, context, name, null, null, onFetchOnly); + scriptNodes[name] = node; + scriptWaiting.push(name); + } + + //Do a normal require for it, once it loads, use it as return + //value. + req([name], onLoad); + } else { + //Credit to LABjs author Kyle Simpson for finding that scripts + //with type="script/cache" allow scripts to be downloaded into + //browser cache but not executed. Use that + //so that subsequent addition of a real type="text/javascript" + //tag will cause the scripts to be executed immediately in the + //correct order. + if (req.specified(name)) { + req([name], onLoad); + } else { + cacheWaiting.push({ + name: name, + req: req, + onLoad: onLoad + }); + require.attach(url, null, name, scriptCacheCallback, "script/cache"); + } + } + } + }); +}()); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/prettify.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/prettify.js new file mode 100644 index 000000000..037c26da4 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/prettify.js @@ -0,0 +1,1477 @@ +// Copyright (C) 2006 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +/** + * @fileoverview + * some functions for browser-side pretty printing of code contained in html. + * + * <p> + * For a fairly comprehensive set of languages see the + * <a href="http://google-code-prettify.googlecode.com/svn/trunk/README.html#langs">README</a> + * file that came with this source. At a minimum, the lexer should work on a + * number of languages including C and friends, Java, Python, Bash, SQL, HTML, + * XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP and Awk + * and a subset of Perl, but, because of commenting conventions, doesn't work on + * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class. + * <p> + * Usage: <ol> + * <li> include this source file in an html page via + * {@code <script type="text/javascript" src="/path/to/prettify.js"></script>} + * <li> define style rules. See the example page for examples. + * <li> mark the {@code <pre>} and {@code <code>} tags in your source with + * {@code class=prettyprint.} + * You can also use the (html deprecated) {@code <xmp>} tag, but the pretty + * printer needs to do more substantial DOM manipulations to support that, so + * some css styles may not be preserved. + * </ol> + * That's it. I wanted to keep the API as simple as possible, so there's no + * need to specify which language the code is in, but if you wish, you can add + * another class to the {@code <pre>} or {@code <code>} element to specify the + * language, as in {@code <pre class="prettyprint lang-java">}. Any class that + * starts with "lang-" followed by a file extension, specifies the file type. + * See the "lang-*.js" files in this directory for code that implements + * per-language file handlers. + * <p> + * Change log:<br> + * cbeust, 2006/08/22 + * <blockquote> + * Java annotations (start with "@") are now captured as literals ("lit") + * </blockquote> + * @requires console + */ + +// JSLint declarations +/*global console, document, navigator, setTimeout, window */ + +/** + * Split {@code prettyPrint} into multiple timeouts so as not to interfere with + * UI events. + * If set to {@code false}, {@code prettyPrint()} is synchronous. + */ +window['PR_SHOULD_USE_CONTINUATION'] = true; + +(function () { + // Keyword lists for various languages. + // We use things that coerce to strings to make them compact when minified + // and to defeat aggressive optimizers that fold large string constants. + var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"]; + var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," + + "double,enum,extern,float,goto,int,long,register,short,signed,sizeof," + + "static,struct,switch,typedef,union,unsigned,void,volatile"]; + var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," + + "new,operator,private,protected,public,this,throw,true,try,typeof"]; + var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignof,align_union,asm,axiom,bool," + + "concept,concept_map,const_cast,constexpr,decltype," + + "dynamic_cast,explicit,export,friend,inline,late_check," + + "mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast," + + "template,typeid,typename,using,virtual,where"]; + var JAVA_KEYWORDS = [COMMON_KEYWORDS, + "abstract,boolean,byte,extends,final,finally,implements,import," + + "instanceof,null,native,package,strictfp,super,synchronized,throws," + + "transient"]; + var CSHARP_KEYWORDS = [JAVA_KEYWORDS, + "as,base,by,checked,decimal,delegate,descending,dynamic,event," + + "fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock," + + "object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed," + + "stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"]; + var COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally," + + "for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then," + + "true,try,unless,until,when,while,yes"; + var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS, + "debugger,eval,export,function,get,null,set,undefined,var,with," + + "Infinity,NaN"]; + var PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for," + + "goto,if,import,last,local,my,next,no,our,print,package,redo,require," + + "sub,undef,unless,until,use,wantarray,while,BEGIN,END"; + var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," + + "elif,except,exec,finally,from,global,import,in,is,lambda," + + "nonlocal,not,or,pass,print,raise,try,with,yield," + + "False,True,None"]; + var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," + + "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," + + "rescue,retry,self,super,then,true,undef,unless,until,when,yield," + + "BEGIN,END"]; + var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," + + "function,in,local,set,then,until"]; + var ALL_KEYWORDS = [ + CPP_KEYWORDS, CSHARP_KEYWORDS, JSCRIPT_KEYWORDS, PERL_KEYWORDS + + PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS]; + var C_TYPES = /^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/; + + // token style names. correspond to css classes + /** + * token style for a string literal + * @const + */ + var PR_STRING = 'str'; + /** + * token style for a keyword + * @const + */ + var PR_KEYWORD = 'kwd'; + /** + * token style for a comment + * @const + */ + var PR_COMMENT = 'com'; + /** + * token style for a type + * @const + */ + var PR_TYPE = 'typ'; + /** + * token style for a literal value. e.g. 1, null, true. + * @const + */ + var PR_LITERAL = 'lit'; + /** + * token style for a punctuation string. + * @const + */ + var PR_PUNCTUATION = 'pun'; + /** + * token style for a punctuation string. + * @const + */ + var PR_PLAIN = 'pln'; + + /** + * token style for an sgml tag. + * @const + */ + var PR_TAG = 'tag'; + /** + * token style for a markup declaration such as a DOCTYPE. + * @const + */ + var PR_DECLARATION = 'dec'; + /** + * token style for embedded source. + * @const + */ + var PR_SOURCE = 'src'; + /** + * token style for an sgml attribute name. + * @const + */ + var PR_ATTRIB_NAME = 'atn'; + /** + * token style for an sgml attribute value. + * @const + */ + var PR_ATTRIB_VALUE = 'atv'; + + /** + * A class that indicates a section of markup that is not code, e.g. to allow + * embedding of line numbers within code listings. + * @const + */ + var PR_NOCODE = 'nocode'; + + + +/** + * A set of tokens that can precede a regular expression literal in + * javascript + * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html + * has the full list, but I've removed ones that might be problematic when + * seen in languages that don't support regular expression literals. + * + * <p>Specifically, I've removed any keywords that can't precede a regexp + * literal in a syntactically legal javascript program, and I've removed the + * "in" keyword since it's not a keyword in many languages, and might be used + * as a count of inches. + * + * <p>The link a above does not accurately describe EcmaScript rules since + * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works + * very well in practice. + * + * @private + * @const + */ +var REGEXP_PRECEDER_PATTERN = '(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*'; + +// CAVEAT: this does not properly handle the case where a regular +// expression immediately follows another since a regular expression may +// have flags for case-sensitivity and the like. Having regexp tokens +// adjacent is not valid in any language I'm aware of, so I'm punting. +// TODO: maybe style special characters inside a regexp as punctuation. + + + /** + * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally + * matches the union of the sets of strings matched by the input RegExp. + * Since it matches globally, if the input strings have a start-of-input + * anchor (/^.../), it is ignored for the purposes of unioning. + * @param {Array.<RegExp>} regexs non multiline, non-global regexs. + * @return {RegExp} a global regex. + */ + function combinePrefixPatterns(regexs) { + var capturedGroupIndex = 0; + + var needToFoldCase = false; + var ignoreCase = false; + for (var i = 0, n = regexs.length; i < n; ++i) { + var regex = regexs[i]; + if (regex.ignoreCase) { + ignoreCase = true; + } else if (/[a-z]/i.test(regex.source.replace( + /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) { + needToFoldCase = true; + ignoreCase = false; + break; + } + } + + var escapeCharToCodeUnit = { + 'b': 8, + 't': 9, + 'n': 0xa, + 'v': 0xb, + 'f': 0xc, + 'r': 0xd + }; + + function decodeEscape(charsetPart) { + var cc0 = charsetPart.charCodeAt(0); + if (cc0 !== 92 /* \\ */) { + return cc0; + } + var c1 = charsetPart.charAt(1); + cc0 = escapeCharToCodeUnit[c1]; + if (cc0) { + return cc0; + } else if ('0' <= c1 && c1 <= '7') { + return parseInt(charsetPart.substring(1), 8); + } else if (c1 === 'u' || c1 === 'x') { + return parseInt(charsetPart.substring(2), 16); + } else { + return charsetPart.charCodeAt(1); + } + } + + function encodeEscape(charCode) { + if (charCode < 0x20) { + return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16); + } + var ch = String.fromCharCode(charCode); + if (ch === '\\' || ch === '-' || ch === '[' || ch === ']') { + ch = '\\' + ch; + } + return ch; + } + + function caseFoldCharset(charSet) { + var charsetParts = charSet.substring(1, charSet.length - 1).match( + new RegExp( + '\\\\u[0-9A-Fa-f]{4}' + + '|\\\\x[0-9A-Fa-f]{2}' + + '|\\\\[0-3][0-7]{0,2}' + + '|\\\\[0-7]{1,2}' + + '|\\\\[\\s\\S]' + + '|-' + + '|[^-\\\\]', + 'g')); + var groups = []; + var ranges = []; + var inverse = charsetParts[0] === '^'; + for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) { + var p = charsetParts[i]; + if (/\\[bdsw]/i.test(p)) { // Don't muck with named groups. + groups.push(p); + } else { + var start = decodeEscape(p); + var end; + if (i + 2 < n && '-' === charsetParts[i + 1]) { + end = decodeEscape(charsetParts[i + 2]); + i += 2; + } else { + end = start; + } + ranges.push([start, end]); + // If the range might intersect letters, then expand it. + // This case handling is too simplistic. + // It does not deal with non-latin case folding. + // It works for latin source code identifiers though. + if (!(end < 65 || start > 122)) { + if (!(end < 65 || start > 90)) { + ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]); + } + if (!(end < 97 || start > 122)) { + ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]); + } + } + } + } + + // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]] + // -> [[1, 12], [14, 14], [16, 17]] + ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1] - a[1]); }); + var consolidatedRanges = []; + var lastRange = [NaN, NaN]; + for (var i = 0; i < ranges.length; ++i) { + var range = ranges[i]; + if (range[0] <= lastRange[1] + 1) { + lastRange[1] = Math.max(lastRange[1], range[1]); + } else { + consolidatedRanges.push(lastRange = range); + } + } + + var out = ['[']; + if (inverse) { out.push('^'); } + out.push.apply(out, groups); + for (var i = 0; i < consolidatedRanges.length; ++i) { + var range = consolidatedRanges[i]; + out.push(encodeEscape(range[0])); + if (range[1] > range[0]) { + if (range[1] + 1 > range[0]) { out.push('-'); } + out.push(encodeEscape(range[1])); + } + } + out.push(']'); + return out.join(''); + } + + function allowAnywhereFoldCaseAndRenumberGroups(regex) { + // Split into character sets, escape sequences, punctuation strings + // like ('(', '(?:', ')', '^'), and runs of characters that do not + // include any of the above. + var parts = regex.source.match( + new RegExp( + '(?:' + + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]' // a character set + + '|\\\\u[A-Fa-f0-9]{4}' // a unicode escape + + '|\\\\x[A-Fa-f0-9]{2}' // a hex escape + + '|\\\\[0-9]+' // a back-reference or octal escape + + '|\\\\[^ux0-9]' // other escape sequence + + '|\\(\\?[:!=]' // start of a non-capturing group + + '|[\\(\\)\\^]' // start/emd of a group, or line start + + '|[^\\x5B\\x5C\\(\\)\\^]+' // run of other characters + + ')', + 'g')); + var n = parts.length; + + // Maps captured group numbers to the number they will occupy in + // the output or to -1 if that has not been determined, or to + // undefined if they need not be capturing in the output. + var capturedGroups = []; + + // Walk over and identify back references to build the capturedGroups + // mapping. + for (var i = 0, groupIndex = 0; i < n; ++i) { + var p = parts[i]; + if (p === '(') { + // groups are 1-indexed, so max group index is count of '(' + ++groupIndex; + } else if ('\\' === p.charAt(0)) { + var decimalValue = +p.substring(1); + if (decimalValue && decimalValue <= groupIndex) { + capturedGroups[decimalValue] = -1; + } + } + } + + // Renumber groups and reduce capturing groups to non-capturing groups + // where possible. + for (var i = 1; i < capturedGroups.length; ++i) { + if (-1 === capturedGroups[i]) { + capturedGroups[i] = ++capturedGroupIndex; + } + } + for (var i = 0, groupIndex = 0; i < n; ++i) { + var p = parts[i]; + if (p === '(') { + ++groupIndex; + if (capturedGroups[groupIndex] === undefined) { + parts[i] = '(?:'; + } + } else if ('\\' === p.charAt(0)) { + var decimalValue = +p.substring(1); + if (decimalValue && decimalValue <= groupIndex) { + parts[i] = '\\' + capturedGroups[groupIndex]; + } + } + } + + // Remove any prefix anchors so that the output will match anywhere. + // ^^ really does mean an anchored match though. + for (var i = 0, groupIndex = 0; i < n; ++i) { + if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; } + } + + // Expand letters to groups to handle mixing of case-sensitive and + // case-insensitive patterns if necessary. + if (regex.ignoreCase && needToFoldCase) { + for (var i = 0; i < n; ++i) { + var p = parts[i]; + var ch0 = p.charAt(0); + if (p.length >= 2 && ch0 === '[') { + parts[i] = caseFoldCharset(p); + } else if (ch0 !== '\\') { + // TODO: handle letters in numeric escapes. + parts[i] = p.replace( + /[a-zA-Z]/g, + function (ch) { + var cc = ch.charCodeAt(0); + return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']'; + }); + } + } + } + + return parts.join(''); + } + + var rewritten = []; + for (var i = 0, n = regexs.length; i < n; ++i) { + var regex = regexs[i]; + if (regex.global || regex.multiline) { throw new Error('' + regex); } + rewritten.push( + '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')'); + } + + return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g'); + } + + + /** + * Split markup into a string of source code and an array mapping ranges in + * that string to the text nodes in which they appear. + * + * <p> + * The HTML DOM structure:</p> + * <pre> + * (Element "p" + * (Element "b" + * (Text "print ")) ; #1 + * (Text "'Hello '") ; #2 + * (Element "br") ; #3 + * (Text " + 'World';")) ; #4 + * </pre> + * <p> + * corresponds to the HTML + * {@code <p><b>print </b>'Hello '<br> + 'World';</p>}.</p> + * + * <p> + * It will produce the output:</p> + * <pre> + * { + * sourceCode: "print 'Hello '\n + 'World';", + * // 1 2 + * // 012345678901234 5678901234567 + * spans: [0, #1, 6, #2, 14, #3, 15, #4] + * } + * </pre> + * <p> + * where #1 is a reference to the {@code "print "} text node above, and so + * on for the other text nodes. + * </p> + * + * <p> + * The {@code} spans array is an array of pairs. Even elements are the start + * indices of substrings, and odd elements are the text nodes (or BR elements) + * that contain the text for those substrings. + * Substrings continue until the next index or the end of the source. + * </p> + * + * @param {Node} node an HTML DOM subtree containing source-code. + * @return {Object} source code and the text nodes in which they occur. + */ + function extractSourceSpans(node) { + var nocode = /(?:^|\s)nocode(?:\s|$)/; + + var chunks = []; + var length = 0; + var spans = []; + var k = 0; + + var whitespace; + if (node.currentStyle) { + whitespace = node.currentStyle.whiteSpace; + } else if (window.getComputedStyle) { + whitespace = document.defaultView.getComputedStyle(node, null) + .getPropertyValue('white-space'); + } + var isPreformatted = whitespace && 'pre' === whitespace.substring(0, 3); + + function walk(node) { + switch (node.nodeType) { + case 1: // Element + if (nocode.test(node.className)) { return; } + for (var child = node.firstChild; child; child = child.nextSibling) { + walk(child); + } + var nodeName = node.nodeName; + if ('BR' === nodeName || 'LI' === nodeName) { + chunks[k] = '\n'; + spans[k << 1] = length++; + spans[(k++ << 1) | 1] = node; + } + break; + case 3: case 4: // Text + var text = node.nodeValue; + if (text.length) { + if (!isPreformatted) { + text = text.replace(/[ \t\r\n]+/g, ' '); + } else { + text = text.replace(/\r\n?/g, '\n'); // Normalize newlines. + } + // TODO: handle tabs here? + chunks[k] = text; + spans[k << 1] = length; + length += text.length; + spans[(k++ << 1) | 1] = node; + } + break; + } + } + + walk(node); + + return { + sourceCode: chunks.join('').replace(/\n$/, ''), + spans: spans + }; + } + + + /** + * Apply the given language handler to sourceCode and add the resulting + * decorations to out. + * @param {number} basePos the index of sourceCode within the chunk of source + * whose decorations are already present on out. + */ + function appendDecorations(basePos, sourceCode, langHandler, out) { + if (!sourceCode) { return; } + var job = { + sourceCode: sourceCode, + basePos: basePos + }; + langHandler(job); + out.push.apply(out, job.decorations); + } + + var notWs = /\S/; + + /** + * Given an element, if it contains only one child element and any text nodes + * it contains contain only space characters, return the sole child element. + * Otherwise returns undefined. + * <p> + * This is meant to return the CODE element in {@code <pre><code ...>} when + * there is a single child element that contains all the non-space textual + * content, but not to return anything where there are multiple child elements + * as in {@code <pre><code>...</code><code>...</code></pre>} or when there + * is textual content. + */ + function childContentWrapper(element) { + var wrapper = undefined; + for (var c = element.firstChild; c; c = c.nextSibling) { + var type = c.nodeType; + wrapper = (type === 1) // Element Node + ? (wrapper ? element : c) + : (type === 3) // Text Node + ? (notWs.test(c.nodeValue) ? element : wrapper) + : wrapper; + } + return wrapper === element ? undefined : wrapper; + } + + /** Given triples of [style, pattern, context] returns a lexing function, + * The lexing function interprets the patterns to find token boundaries and + * returns a decoration list of the form + * [index_0, style_0, index_1, style_1, ..., index_n, style_n] + * where index_n is an index into the sourceCode, and style_n is a style + * constant like PR_PLAIN. index_n-1 <= index_n, and style_n-1 applies to + * all characters in sourceCode[index_n-1:index_n]. + * + * The stylePatterns is a list whose elements have the form + * [style : string, pattern : RegExp, DEPRECATED, shortcut : string]. + * + * Style is a style constant like PR_PLAIN, or can be a string of the + * form 'lang-FOO', where FOO is a language extension describing the + * language of the portion of the token in $1 after pattern executes. + * E.g., if style is 'lang-lisp', and group 1 contains the text + * '(hello (world))', then that portion of the token will be passed to the + * registered lisp handler for formatting. + * The text before and after group 1 will be restyled using this decorator + * so decorators should take care that this doesn't result in infinite + * recursion. For example, the HTML lexer rule for SCRIPT elements looks + * something like ['lang-js', /<[s]cript>(.+?)<\/script>/]. This may match + * '<script>foo()<\/script>', which would cause the current decorator to + * be called with '<script>' which would not match the same rule since + * group 1 must not be empty, so it would be instead styled as PR_TAG by + * the generic tag rule. The handler registered for the 'js' extension would + * then be called with 'foo()', and finally, the current decorator would + * be called with '<\/script>' which would not match the original rule and + * so the generic tag rule would identify it as a tag. + * + * Pattern must only match prefixes, and if it matches a prefix, then that + * match is considered a token with the same style. + * + * Context is applied to the last non-whitespace, non-comment token + * recognized. + * + * Shortcut is an optional string of characters, any of which, if the first + * character, gurantee that this pattern and only this pattern matches. + * + * @param {Array} shortcutStylePatterns patterns that always start with + * a known character. Must have a shortcut string. + * @param {Array} fallthroughStylePatterns patterns that will be tried in + * order if the shortcut ones fail. May have shortcuts. + * + * @return {function (Object)} a + * function that takes source code and returns a list of decorations. + */ + function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) { + var shortcuts = {}; + var tokenizer; + (function () { + var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns); + var allRegexs = []; + var regexKeys = {}; + for (var i = 0, n = allPatterns.length; i < n; ++i) { + var patternParts = allPatterns[i]; + var shortcutChars = patternParts[3]; + if (shortcutChars) { + for (var c = shortcutChars.length; --c >= 0;) { + shortcuts[shortcutChars.charAt(c)] = patternParts; + } + } + var regex = patternParts[1]; + var k = '' + regex; + if (!regexKeys.hasOwnProperty(k)) { + allRegexs.push(regex); + regexKeys[k] = null; + } + } + allRegexs.push(/[\0-\uffff]/); + tokenizer = combinePrefixPatterns(allRegexs); + })(); + + var nPatterns = fallthroughStylePatterns.length; + + /** + * Lexes job.sourceCode and produces an output array job.decorations of + * style classes preceded by the position at which they start in + * job.sourceCode in order. + * + * @param {Object} job an object like <pre>{ + * sourceCode: {string} sourceText plain text, + * basePos: {int} position of job.sourceCode in the larger chunk of + * sourceCode. + * }</pre> + */ + var decorate = function (job) { + var sourceCode = job.sourceCode, basePos = job.basePos; + /** Even entries are positions in source in ascending order. Odd enties + * are style markers (e.g., PR_COMMENT) that run from that position until + * the end. + * @type {Array.<number|string>} + */ + var decorations = [basePos, PR_PLAIN]; + var pos = 0; // index into sourceCode + var tokens = sourceCode.match(tokenizer) || []; + var styleCache = {}; + + for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) { + var token = tokens[ti]; + var style = styleCache[token]; + var match = void 0; + + var isEmbedded; + if (typeof style === 'string') { + isEmbedded = false; + } else { + var patternParts = shortcuts[token.charAt(0)]; + if (patternParts) { + match = token.match(patternParts[1]); + style = patternParts[0]; + } else { + for (var i = 0; i < nPatterns; ++i) { + patternParts = fallthroughStylePatterns[i]; + match = token.match(patternParts[1]); + if (match) { + style = patternParts[0]; + break; + } + } + + if (!match) { // make sure that we make progress + style = PR_PLAIN; + } + } + + isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5); + if (isEmbedded && !(match && typeof match[1] === 'string')) { + isEmbedded = false; + style = PR_SOURCE; + } + + if (!isEmbedded) { styleCache[token] = style; } + } + + var tokenStart = pos; + pos += token.length; + + if (!isEmbedded) { + decorations.push(basePos + tokenStart, style); + } else { // Treat group 1 as an embedded block of source code. + var embeddedSource = match[1]; + var embeddedSourceStart = token.indexOf(embeddedSource); + var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length; + if (match[2]) { + // If embeddedSource can be blank, then it would match at the + // beginning which would cause us to infinitely recurse on the + // entire token, so we catch the right context in match[2]. + embeddedSourceEnd = token.length - match[2].length; + embeddedSourceStart = embeddedSourceEnd - embeddedSource.length; + } + var lang = style.substring(5); + // Decorate the left of the embedded source + appendDecorations( + basePos + tokenStart, + token.substring(0, embeddedSourceStart), + decorate, decorations); + // Decorate the embedded source + appendDecorations( + basePos + tokenStart + embeddedSourceStart, + embeddedSource, + langHandlerForExtension(lang, embeddedSource), + decorations); + // Decorate the right of the embedded section + appendDecorations( + basePos + tokenStart + embeddedSourceEnd, + token.substring(embeddedSourceEnd), + decorate, decorations); + } + } + job.decorations = decorations; + }; + return decorate; + } + + /** returns a function that produces a list of decorations from source text. + * + * This code treats ", ', and ` as string delimiters, and \ as a string + * escape. It does not recognize perl's qq() style strings. + * It has no special handling for double delimiter escapes as in basic, or + * the tripled delimiters used in python, but should work on those regardless + * although in those cases a single string literal may be broken up into + * multiple adjacent string literals. + * + * It recognizes C, C++, and shell style comments. + * + * @param {Object} options a set of optional parameters. + * @return {function (Object)} a function that examines the source code + * in the input job and builds the decoration list. + */ + function sourceDecorator(options) { + var shortcutStylePatterns = [], fallthroughStylePatterns = []; + if (options['tripleQuotedStrings']) { + // '''multi-line-string''', 'single-line-string', and double-quoted + shortcutStylePatterns.push( + [PR_STRING, /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/, + null, '\'"']); + } else if (options['multiLineStrings']) { + // 'multi-line-string', "multi-line-string" + shortcutStylePatterns.push( + [PR_STRING, /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/, + null, '\'"`']); + } else { + // 'single-line-string', "single-line-string" + shortcutStylePatterns.push( + [PR_STRING, + /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/, + null, '"\'']); + } + if (options['verbatimStrings']) { + // verbatim-string-literal production from the C# grammar. See issue 93. + fallthroughStylePatterns.push( + [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]); + } + var hc = options['hashComments']; + if (hc) { + if (options['cStyleComments']) { + if (hc > 1) { // multiline hash comments + shortcutStylePatterns.push( + [PR_COMMENT, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']); + } else { + // Stop C preprocessor declarations at an unclosed open comment + shortcutStylePatterns.push( + [PR_COMMENT, /^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/, + null, '#']); + } + fallthroughStylePatterns.push( + [PR_STRING, + /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/, + null]); + } else { + shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']); + } + } + if (options['cStyleComments']) { + fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]); + fallthroughStylePatterns.push( + [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]); + } + if (options['regexLiterals']) { + /** + * @const + */ + var REGEX_LITERAL = ( + // A regular expression literal starts with a slash that is + // not followed by * or / so that it is not confused with + // comments. + '/(?=[^/*])' + // and then contains any number of raw characters, + + '(?:[^/\\x5B\\x5C]' + // escape sequences (\x5C), + + '|\\x5C[\\s\\S]' + // or non-nesting character sets (\x5B\x5D); + + '|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+' + // finally closed by a /. + + '/'); + fallthroughStylePatterns.push( + ['lang-regex', + new RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')') + ]); + } + + var types = options['types']; + if (types) { + fallthroughStylePatterns.push([PR_TYPE, types]); + } + + var keywords = ("" + options['keywords']).replace(/^ | $/g, ''); + if (keywords.length) { + fallthroughStylePatterns.push( + [PR_KEYWORD, + new RegExp('^(?:' + keywords.replace(/[\s,]+/g, '|') + ')\\b'), + null]); + } + + shortcutStylePatterns.push([PR_PLAIN, /^\s+/, null, ' \r\n\t\xA0']); + fallthroughStylePatterns.push( + // TODO(mikesamuel): recognize non-latin letters and numerals in idents + [PR_LITERAL, /^@[a-z_$][a-z_$@0-9]*/i, null], + [PR_TYPE, /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/, null], + [PR_PLAIN, /^[a-z_$][a-z_$@0-9]*/i, null], + [PR_LITERAL, + new RegExp( + '^(?:' + // A hex number + + '0x[a-f0-9]+' + // or an octal or decimal number, + + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)' + // possibly in scientific notation + + '(?:e[+\\-]?\\d+)?' + + ')' + // with an optional modifier like UL for unsigned long + + '[a-z]*', 'i'), + null, '0123456789'], + // Don't treat escaped quotes in bash as starting strings. See issue 144. + [PR_PLAIN, /^\\[\s\S]?/, null], + [PR_PUNCTUATION, /^.[^\s\w\.$@\'\"\`\/\#\\]*/, null]); + + return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns); + } + + var decorateSource = sourceDecorator({ + 'keywords': ALL_KEYWORDS, + 'hashComments': true, + 'cStyleComments': true, + 'multiLineStrings': true, + 'regexLiterals': true + }); + + /** + * Given a DOM subtree, wraps it in a list, and puts each line into its own + * list item. + * + * @param {Node} node modified in place. Its content is pulled into an + * HTMLOListElement, and each line is moved into a separate list item. + * This requires cloning elements, so the input might not have unique + * IDs after numbering. + */ + function numberLines(node, opt_startLineNum) { + var nocode = /(?:^|\s)nocode(?:\s|$)/; + var lineBreak = /\r\n?|\n/; + + var document = node.ownerDocument; + + var whitespace; + if (node.currentStyle) { + whitespace = node.currentStyle.whiteSpace; + } else if (window.getComputedStyle) { + whitespace = document.defaultView.getComputedStyle(node, null) + .getPropertyValue('white-space'); + } + // If it's preformatted, then we need to split lines on line breaks + // in addition to <BR>s. + var isPreformatted = whitespace && 'pre' === whitespace.substring(0, 3); + + var li = document.createElement('LI'); + while (node.firstChild) { + li.appendChild(node.firstChild); + } + // An array of lines. We split below, so this is initialized to one + // un-split line. + var listItems = [li]; + + function walk(node) { + switch (node.nodeType) { + case 1: // Element + if (nocode.test(node.className)) { break; } + if ('BR' === node.nodeName) { + breakAfter(node); + // Discard the <BR> since it is now flush against a </LI>. + if (node.parentNode) { + node.parentNode.removeChild(node); + } + } else { + for (var child = node.firstChild; child; child = child.nextSibling) { + walk(child); + } + } + break; + case 3: case 4: // Text + if (isPreformatted) { + var text = node.nodeValue; + var match = text.match(lineBreak); + if (match) { + var firstLine = text.substring(0, match.index); + node.nodeValue = firstLine; + var tail = text.substring(match.index + match[0].length); + if (tail) { + var parent = node.parentNode; + parent.insertBefore( + document.createTextNode(tail), node.nextSibling); + } + breakAfter(node); + if (!firstLine) { + // Don't leave blank text nodes in the DOM. + node.parentNode.removeChild(node); + } + } + } + break; + } + } + + // Split a line after the given node. + function breakAfter(lineEndNode) { + // If there's nothing to the right, then we can skip ending the line + // here, and move root-wards since splitting just before an end-tag + // would require us to create a bunch of empty copies. + while (!lineEndNode.nextSibling) { + lineEndNode = lineEndNode.parentNode; + if (!lineEndNode) { return; } + } + + function breakLeftOf(limit, copy) { + // Clone shallowly if this node needs to be on both sides of the break. + var rightSide = copy ? limit.cloneNode(false) : limit; + var parent = limit.parentNode; + if (parent) { + // We clone the parent chain. + // This helps us resurrect important styling elements that cross lines. + // E.g. in <i>Foo<br>Bar</i> + // should be rewritten to <li><i>Foo</i></li><li><i>Bar</i></li>. + var parentClone = breakLeftOf(parent, 1); + // Move the clone and everything to the right of the original + // onto the cloned parent. + var next = limit.nextSibling; + parentClone.appendChild(rightSide); + for (var sibling = next; sibling; sibling = next) { + next = sibling.nextSibling; + parentClone.appendChild(sibling); + } + } + return rightSide; + } + + var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0); + + // Walk the parent chain until we reach an unattached LI. + for (var parent; + // Check nodeType since IE invents document fragments. + (parent = copiedListItem.parentNode) && parent.nodeType === 1;) { + copiedListItem = parent; + } + // Put it on the list of lines for later processing. + listItems.push(copiedListItem); + } + + // Split lines while there are lines left to split. + for (var i = 0; // Number of lines that have been split so far. + i < listItems.length; // length updated by breakAfter calls. + ++i) { + walk(listItems[i]); + } + + // Make sure numeric indices show correctly. + if (opt_startLineNum === (opt_startLineNum|0)) { + listItems[0].setAttribute('value', opt_startLineNum); + } + + var ol = document.createElement('OL'); + ol.className = 'linenums'; + var offset = Math.max(0, ((opt_startLineNum - 1 /* zero index */)) | 0) || 0; + for (var i = 0, n = listItems.length; i < n; ++i) { + li = listItems[i]; + // Stick a class on the LIs so that stylesheets can + // color odd/even rows, or any other row pattern that + // is co-prime with 10. + li.className = 'L' + ((i + offset) % 10); + if (!li.firstChild) { + li.appendChild(document.createTextNode('\xA0')); + } + ol.appendChild(li); + } + + node.appendChild(ol); + } + + /** + * Breaks {@code job.sourceCode} around style boundaries in + * {@code job.decorations} and modifies {@code job.sourceNode} in place. + * @param {Object} job like <pre>{ + * sourceCode: {string} source as plain text, + * spans: {Array.<number|Node>} alternating span start indices into source + * and the text node or element (e.g. {@code <BR>}) corresponding to that + * span. + * decorations: {Array.<number|string} an array of style classes preceded + * by the position at which they start in job.sourceCode in order + * }</pre> + * @private + */ + function recombineTagsAndDecorations(job) { + var isIE = /\bMSIE\b/.test(navigator.userAgent); + var newlineRe = /\n/g; + + var source = job.sourceCode; + var sourceLength = source.length; + // Index into source after the last code-unit recombined. + var sourceIndex = 0; + + var spans = job.spans; + var nSpans = spans.length; + // Index into spans after the last span which ends at or before sourceIndex. + var spanIndex = 0; + + var decorations = job.decorations; + var nDecorations = decorations.length; + // Index into decorations after the last decoration which ends at or before + // sourceIndex. + var decorationIndex = 0; + + // Remove all zero-length decorations. + decorations[nDecorations] = sourceLength; + var decPos, i; + for (i = decPos = 0; i < nDecorations;) { + if (decorations[i] !== decorations[i + 2]) { + decorations[decPos++] = decorations[i++]; + decorations[decPos++] = decorations[i++]; + } else { + i += 2; + } + } + nDecorations = decPos; + + // Simplify decorations. + for (i = decPos = 0; i < nDecorations;) { + var startPos = decorations[i]; + // Conflate all adjacent decorations that use the same style. + var startDec = decorations[i + 1]; + var end = i + 2; + while (end + 2 <= nDecorations && decorations[end + 1] === startDec) { + end += 2; + } + decorations[decPos++] = startPos; + decorations[decPos++] = startDec; + i = end; + } + + nDecorations = decorations.length = decPos; + + var decoration = null; + while (spanIndex < nSpans) { + var spanStart = spans[spanIndex]; + var spanEnd = spans[spanIndex + 2] || sourceLength; + + var decStart = decorations[decorationIndex]; + var decEnd = decorations[decorationIndex + 2] || sourceLength; + + var end = Math.min(spanEnd, decEnd); + + var textNode = spans[spanIndex + 1]; + var styledText; + if (textNode.nodeType !== 1 // Don't muck with <BR>s or <LI>s + // Don't introduce spans around empty text nodes. + && (styledText = source.substring(sourceIndex, end))) { + // This may seem bizarre, and it is. Emitting LF on IE causes the + // code to display with spaces instead of line breaks. + // Emitting Windows standard issue linebreaks (CRLF) causes a blank + // space to appear at the beginning of every line but the first. + // Emitting an old Mac OS 9 line separator makes everything spiffy. + if (isIE) { styledText = styledText.replace(newlineRe, '\r'); } + textNode.nodeValue = styledText; + var document = textNode.ownerDocument; + var span = document.createElement('SPAN'); + span.className = decorations[decorationIndex + 1]; + var parentNode = textNode.parentNode; + parentNode.replaceChild(span, textNode); + span.appendChild(textNode); + if (sourceIndex < spanEnd) { // Split off a text node. + spans[spanIndex + 1] = textNode + // TODO: Possibly optimize by using '' if there's no flicker. + = document.createTextNode(source.substring(end, spanEnd)); + parentNode.insertBefore(textNode, span.nextSibling); + } + } + + sourceIndex = end; + + if (sourceIndex >= spanEnd) { + spanIndex += 2; + } + if (sourceIndex >= decEnd) { + decorationIndex += 2; + } + } + } + + + /** Maps language-specific file extensions to handlers. */ + var langHandlerRegistry = {}; + /** Register a language handler for the given file extensions. + * @param {function (Object)} handler a function from source code to a list + * of decorations. Takes a single argument job which describes the + * state of the computation. The single parameter has the form + * {@code { + * sourceCode: {string} as plain text. + * decorations: {Array.<number|string>} an array of style classes + * preceded by the position at which they start in + * job.sourceCode in order. + * The language handler should assigned this field. + * basePos: {int} the position of source in the larger source chunk. + * All positions in the output decorations array are relative + * to the larger source chunk. + * } } + * @param {Array.<string>} fileExtensions + */ + function registerLangHandler(handler, fileExtensions) { + for (var i = fileExtensions.length; --i >= 0;) { + var ext = fileExtensions[i]; + if (!langHandlerRegistry.hasOwnProperty(ext)) { + langHandlerRegistry[ext] = handler; + } else if (window['console']) { + console['warn']('cannot override language handler %s', ext); + } + } + } + function langHandlerForExtension(extension, source) { + if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) { + // Treat it as markup if the first non whitespace character is a < and + // the last non-whitespace character is a >. + extension = /^\s*</.test(source) + ? 'default-markup' + : 'default-code'; + } + return langHandlerRegistry[extension]; + } + registerLangHandler(decorateSource, ['default-code']); + registerLangHandler( + createSimpleLexer( + [], + [ + [PR_PLAIN, /^[^<?]+/], + [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/], + [PR_COMMENT, /^<\!--[\s\S]*?(?:-\->|$)/], + // Unescaped content in an unknown language + ['lang-', /^<\?([\s\S]+?)(?:\?>|$)/], + ['lang-', /^<%([\s\S]+?)(?:%>|$)/], + [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/], + ['lang-', /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i], + // Unescaped content in javascript. (Or possibly vbscript). + ['lang-js', /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i], + // Contains unescaped stylesheet content + ['lang-css', /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i], + ['lang-in.tag', /^(<\/?[a-z][^<>]*>)/i] + ]), + ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']); + registerLangHandler( + createSimpleLexer( + [ + [PR_PLAIN, /^[\s]+/, null, ' \t\r\n'], + [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\''] + ], + [ + [PR_TAG, /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i], + [PR_ATTRIB_NAME, /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i], + ['lang-uq.val', /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/], + [PR_PUNCTUATION, /^[=<>\/]+/], + ['lang-js', /^on\w+\s*=\s*\"([^\"]+)\"/i], + ['lang-js', /^on\w+\s*=\s*\'([^\']+)\'/i], + ['lang-js', /^on\w+\s*=\s*([^\"\'>\s]+)/i], + ['lang-css', /^style\s*=\s*\"([^\"]+)\"/i], + ['lang-css', /^style\s*=\s*\'([^\']+)\'/i], + ['lang-css', /^style\s*=\s*([^\"\'>\s]+)/i] + ]), + ['in.tag']); + registerLangHandler( + createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']); + registerLangHandler(sourceDecorator({ + 'keywords': CPP_KEYWORDS, + 'hashComments': true, + 'cStyleComments': true, + 'types': C_TYPES + }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']); + registerLangHandler(sourceDecorator({ + 'keywords': 'null,true,false' + }), ['json']); + registerLangHandler(sourceDecorator({ + 'keywords': CSHARP_KEYWORDS, + 'hashComments': true, + 'cStyleComments': true, + 'verbatimStrings': true, + 'types': C_TYPES + }), ['cs']); + registerLangHandler(sourceDecorator({ + 'keywords': JAVA_KEYWORDS, + 'cStyleComments': true + }), ['java']); + registerLangHandler(sourceDecorator({ + 'keywords': SH_KEYWORDS, + 'hashComments': true, + 'multiLineStrings': true + }), ['bsh', 'csh', 'sh']); + registerLangHandler(sourceDecorator({ + 'keywords': PYTHON_KEYWORDS, + 'hashComments': true, + 'multiLineStrings': true, + 'tripleQuotedStrings': true + }), ['cv', 'py']); + registerLangHandler(sourceDecorator({ + 'keywords': PERL_KEYWORDS, + 'hashComments': true, + 'multiLineStrings': true, + 'regexLiterals': true + }), ['perl', 'pl', 'pm']); + registerLangHandler(sourceDecorator({ + 'keywords': RUBY_KEYWORDS, + 'hashComments': true, + 'multiLineStrings': true, + 'regexLiterals': true + }), ['rb']); + registerLangHandler(sourceDecorator({ + 'keywords': JSCRIPT_KEYWORDS, + 'cStyleComments': true, + 'regexLiterals': true + }), ['js']); + registerLangHandler(sourceDecorator({ + 'keywords': COFFEE_KEYWORDS, + 'hashComments': 3, // ### style block comments + 'cStyleComments': true, + 'multilineStrings': true, + 'tripleQuotedStrings': true, + 'regexLiterals': true + }), ['coffee']); + registerLangHandler(createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']); + + function applyDecorator(job) { + var opt_langExtension = job.langExtension; + + try { + // Extract tags, and convert the source code to plain text. + var sourceAndSpans = extractSourceSpans(job.sourceNode); + /** Plain text. @type {string} */ + var source = sourceAndSpans.sourceCode; + job.sourceCode = source; + job.spans = sourceAndSpans.spans; + job.basePos = 0; + + // Apply the appropriate language handler + langHandlerForExtension(opt_langExtension, source)(job); + + // Integrate the decorations and tags back into the source code, + // modifying the sourceNode in place. + recombineTagsAndDecorations(job); + } catch (e) { + if ('console' in window) { + console['log'](e && e['stack'] ? e['stack'] : e); + } + } + } + + /** + * @param sourceCodeHtml {string} The HTML to pretty print. + * @param opt_langExtension {string} The language name to use. + * Typically, a filename extension like 'cpp' or 'java'. + * @param opt_numberLines {number|boolean} True to number lines, + * or the 1-indexed number of the first line in sourceCodeHtml. + */ + function prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) { + var container = document.createElement('PRE'); + // This could cause images to load and onload listeners to fire. + // E.g. <img onerror="alert(1337)" src="nosuchimage.png">. + // We assume that the inner HTML is from a trusted source. + container.innerHTML = sourceCodeHtml; + if (opt_numberLines) { + numberLines(container, opt_numberLines); + } + + var job = { + langExtension: opt_langExtension, + numberLines: opt_numberLines, + sourceNode: container + }; + applyDecorator(job); + return container.innerHTML; + } + + function prettyPrint(opt_whenDone) { + function byTagName(tn) { return document.getElementsByTagName(tn); } + // fetch a list of nodes to rewrite + var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')]; + var elements = []; + for (var i = 0; i < codeSegments.length; ++i) { + for (var j = 0, n = codeSegments[i].length; j < n; ++j) { + elements.push(codeSegments[i][j]); + } + } + codeSegments = null; + + var clock = Date; + if (!clock['now']) { + clock = { 'now': function () { return +(new Date); } }; + } + + // The loop is broken into a series of continuations to make sure that we + // don't make the browser unresponsive when rewriting a large page. + var k = 0; + var prettyPrintingJob; + + var langExtensionRe = /\blang(?:uage)?-([\w.]+)(?!\S)/; + var prettyPrintRe = /\bprettyprint\b/; + + function doWork() { + var endTime = (window['PR_SHOULD_USE_CONTINUATION'] ? + clock['now']() + 250 /* ms */ : + Infinity); + for (; k < elements.length && clock['now']() < endTime; k++) { + var cs = elements[k]; + var className = cs.className; + if (className.indexOf('prettyprint') >= 0) { + // If the classes includes a language extensions, use it. + // Language extensions can be specified like + // <pre class="prettyprint lang-cpp"> + // the language extension "cpp" is used to find a language handler as + // passed to PR.registerLangHandler. + // HTML5 recommends that a language be specified using "language-" + // as the prefix instead. Google Code Prettify supports both. + // http://dev.w3.org/html5/spec-author-view/the-code-element.html + var langExtension = className.match(langExtensionRe); + // Support <pre class="prettyprint"><code class="language-c"> + var wrapper; + if (!langExtension && (wrapper = childContentWrapper(cs)) + && "CODE" === wrapper.tagName) { + langExtension = wrapper.className.match(langExtensionRe); + } + + if (langExtension) { + langExtension = langExtension[1]; + } + + // make sure this is not nested in an already prettified element + var nested = false; + for (var p = cs.parentNode; p; p = p.parentNode) { + if ((p.tagName === 'pre' || p.tagName === 'code' || + p.tagName === 'xmp') && + p.className && p.className.indexOf('prettyprint') >= 0) { + nested = true; + break; + } + } + if (!nested) { + // Look for a class like linenums or linenums:<n> where <n> is the + // 1-indexed number of the first line. + var lineNums = cs.className.match(/\blinenums\b(?::(\d+))?/); + lineNums = lineNums + ? lineNums[1] && lineNums[1].length ? +lineNums[1] : true + : false; + if (lineNums) { numberLines(cs, lineNums); } + + // do the pretty printing + prettyPrintingJob = { + langExtension: langExtension, + sourceNode: cs, + numberLines: lineNums + }; + applyDecorator(prettyPrintingJob); + } + } + } + if (k < elements.length) { + // finish up in a continuation + setTimeout(doWork, 250); + } else if (opt_whenDone) { + opt_whenDone(); + } + } + + doWork(); + } + + /** + * Find all the {@code <pre>} and {@code <code>} tags in the DOM with + * {@code class=prettyprint} and prettify them. + * + * @param {Function?} opt_whenDone if specified, called when the last entry + * has been finished. + */ + window['prettyPrintOne'] = prettyPrintOne; + /** + * Pretty print a chunk of code. + * + * @param {string} sourceCodeHtml code as html + * @return {string} code as html, but prettier + */ + window['prettyPrint'] = prettyPrint; + /** + * Contains functions for creating and registering new language handlers. + * @type {Object} + */ + window['PR'] = { + 'createSimpleLexer': createSimpleLexer, + 'registerLangHandler': registerLangHandler, + 'sourceDecorator': sourceDecorator, + 'PR_ATTRIB_NAME': PR_ATTRIB_NAME, + 'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE, + 'PR_COMMENT': PR_COMMENT, + 'PR_DECLARATION': PR_DECLARATION, + 'PR_KEYWORD': PR_KEYWORD, + 'PR_LITERAL': PR_LITERAL, + 'PR_NOCODE': PR_NOCODE, + 'PR_PLAIN': PR_PLAIN, + 'PR_PUNCTUATION': PR_PUNCTUATION, + 'PR_SOURCE': PR_SOURCE, + 'PR_STRING': PR_STRING, + 'PR_TAG': PR_TAG, + 'PR_TYPE': PR_TYPE + }; +})(); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/purl-2.2.1.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/purl-2.2.1.js new file mode 100644 index 000000000..509ca0877 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/purl-2.2.1.js @@ -0,0 +1,271 @@ +/* + * JQuery URL Parser plugin, v2.2.1 + * Developed and maintanined by Mark Perkins, mark@allmarkedup.com + * Source repository: https://github.com/allmarkedup/jQuery-URL-Parser + * Licensed under an MIT-style license. See https://github.com/allmarkedup/jQuery-URL-Parser/blob/master/LICENSE for details. + */ + +;(function(factory) { + if (typeof define === 'function' && define.amd) { + // AMD available; use anonymous module + if ( typeof jQuery !== 'undefined' ) { + define(['jquery'], factory); + } else { + define([], factory); + } + } else { + // No AMD available; mutate global vars + if ( typeof jQuery !== 'undefined' ) { + factory(jQuery); + } else { + factory(); + } + } +})(function($, undefined) { + + var tag2attr = { + a : 'href', + img : 'src', + form : 'action', + base : 'href', + script : 'src', + iframe : 'src', + link : 'href' + }, + + key = ['source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'fragment'], // keys available to query + + aliases = { 'anchor' : 'fragment' }, // aliases for backwards compatability + + parser = { + strict : /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, //less intuitive, more accurate to the specs + loose : /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ // more intuitive, fails on relative paths and deviates from specs + }, + + toString = Object.prototype.toString, + + isint = /^[0-9]+$/; + + function parseUri( url, strictMode ) { + var str = decodeURI( url ), + res = parser[ strictMode || false ? 'strict' : 'loose' ].exec( str ), + uri = { attr : {}, param : {}, seg : {} }, + i = 14; + + while ( i-- ) { + uri.attr[ key[i] ] = res[i] || ''; + } + + // build query and fragment parameters + uri.param['query'] = parseString(uri.attr['query']); + uri.param['fragment'] = parseString(uri.attr['fragment']); + + // split path and fragement into segments + uri.seg['path'] = uri.attr.path.replace(/^\/+|\/+$/g,'').split('/'); + uri.seg['fragment'] = uri.attr.fragment.replace(/^\/+|\/+$/g,'').split('/'); + + // compile a 'base' domain attribute + uri.attr['base'] = uri.attr.host ? (uri.attr.protocol ? uri.attr.protocol+'://'+uri.attr.host : uri.attr.host) + (uri.attr.port ? ':'+uri.attr.port : '') : ''; + + return uri; + }; + + function getAttrName( elm ) { + var tn = elm.tagName; + if ( typeof tn !== 'undefined' ) return tag2attr[tn.toLowerCase()]; + return tn; + } + + function promote(parent, key) { + if (parent[key].length == 0) return parent[key] = {}; + var t = {}; + for (var i in parent[key]) t[i] = parent[key][i]; + parent[key] = t; + return t; + } + + function parse(parts, parent, key, val) { + var part = parts.shift(); + if (!part) { + if (isArray(parent[key])) { + parent[key].push(val); + } else if ('object' == typeof parent[key]) { + parent[key] = val; + } else if ('undefined' == typeof parent[key]) { + parent[key] = val; + } else { + parent[key] = [parent[key], val]; + } + } else { + var obj = parent[key] = parent[key] || []; + if (']' == part) { + if (isArray(obj)) { + if ('' != val) obj.push(val); + } else if ('object' == typeof obj) { + obj[keys(obj).length] = val; + } else { + obj = parent[key] = [parent[key], val]; + } + } else if (~part.indexOf(']')) { + part = part.substr(0, part.length - 1); + if (!isint.test(part) && isArray(obj)) obj = promote(parent, key); + parse(parts, obj, part, val); + // key + } else { + if (!isint.test(part) && isArray(obj)) obj = promote(parent, key); + parse(parts, obj, part, val); + } + } + } + + function merge(parent, key, val) { + if (~key.indexOf(']')) { + var parts = key.split('['), + len = parts.length, + last = len - 1; + parse(parts, parent, 'base', val); + } else { + if (!isint.test(key) && isArray(parent.base)) { + var t = {}; + for (var k in parent.base) t[k] = parent.base[k]; + parent.base = t; + } + set(parent.base, key, val); + } + return parent; + } + + function parseString(str) { + return reduce(String(str).split(/&|;/), function(ret, pair) { + try { + pair = decodeURIComponent(pair.replace(/\+/g, ' ')); + } catch(e) { + // ignore + } + var eql = pair.indexOf('='), + brace = lastBraceInKey(pair), + key = pair.substr(0, brace || eql), + val = pair.substr(brace || eql, pair.length), + val = val.substr(val.indexOf('=') + 1, val.length); + + if ('' == key) key = pair, val = ''; + + return merge(ret, key, val); + }, { base: {} }).base; + } + + function set(obj, key, val) { + var v = obj[key]; + if (undefined === v) { + obj[key] = val; + } else if (isArray(v)) { + v.push(val); + } else { + obj[key] = [v, val]; + } + } + + function lastBraceInKey(str) { + var len = str.length, + brace, c; + for (var i = 0; i < len; ++i) { + c = str[i]; + if (']' == c) brace = false; + if ('[' == c) brace = true; + if ('=' == c && !brace) return i; + } + } + + function reduce(obj, accumulator){ + var i = 0, + l = obj.length >> 0, + curr = arguments[2]; + while (i < l) { + if (i in obj) curr = accumulator.call(undefined, curr, obj[i], i, obj); + ++i; + } + return curr; + } + + function isArray(vArg) { + return Object.prototype.toString.call(vArg) === "[object Array]"; + } + + function keys(obj) { + var keys = []; + for ( prop in obj ) { + if ( obj.hasOwnProperty(prop) ) keys.push(prop); + } + return keys; + } + + function purl( url, strictMode ) { + if ( arguments.length === 1 && url === true ) { + strictMode = true; + url = undefined; + } + strictMode = strictMode || false; + url = url || window.location.toString(); + + return { + + data : parseUri(url, strictMode), + + // get various attributes from the URI + attr : function( attr ) { + attr = aliases[attr] || attr; + return typeof attr !== 'undefined' ? this.data.attr[attr] : this.data.attr; + }, + + // return query string parameters + param : function( param ) { + return typeof param !== 'undefined' ? this.data.param.query[param] : this.data.param.query; + }, + + // return fragment parameters + fparam : function( param ) { + return typeof param !== 'undefined' ? this.data.param.fragment[param] : this.data.param.fragment; + }, + + // return path segments + segment : function( seg ) { + if ( typeof seg === 'undefined' ) { + return this.data.seg.path; + } else { + seg = seg < 0 ? this.data.seg.path.length + seg : seg - 1; // negative segments count from the end + return this.data.seg.path[seg]; + } + }, + + // return fragment segments + fsegment : function( seg ) { + if ( typeof seg === 'undefined' ) { + return this.data.seg.fragment; + } else { + seg = seg < 0 ? this.data.seg.fragment.length + seg : seg - 1; // negative segments count from the end + return this.data.seg.fragment[seg]; + } + } + + }; + + }; + + if ( typeof $ !== 'undefined' ) { + + $.fn.url = function( strictMode ) { + var url = ''; + if ( this.length ) { + url = $(this).attr( getAttrName(this[0]) ) || ''; + } + return purl( url, strictMode ); + }; + + $.url = purl; + + } else { + window.purl = purl; + } + +}); + diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/redback/redback-tmpl.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/redback/redback-tmpl.js new file mode 100644 index 000000000..f9f4e2aae --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/redback/redback-tmpl.js @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +require(['jquery',"jquery.tmpl",'i18n',"utils","text!templates/redback/user-edit.html", + "text!templates/redback/login.html"], + function(jquery,jqueryTmpl,i18n,utils,useredit, login) { + + loadRedbackTemplate=function(){ + + var htmlFragment=$("#html-fragments"); + + // template loading + htmlFragment.append(useredit); + //$.tmpl(useredit).appendTo("#html-fragments"); + $.tmpl(login).appendTo("#html-fragments"); + //htmlFragment.append(login); + $.log("redback-tmpl.js loaded"); + } + } +);
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/redback/redback.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/redback/redback.js new file mode 100644 index 000000000..4faafeefb --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/redback/redback.js @@ -0,0 +1,220 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +define("redback",["jquery","utils","jquery.validate","jquery.json","knockout", + "knockout.simpleGrid","redback.roles","redback.user","redback.users"], function(jquery,utils,jqueryValidate,jqueryJson,ko) { + + // define a container object with various datas + window.redbackModel = {userOperationNames:null,key:null,i18n:$.i18n.map}; + + // unbinding + $("#user-create-form-cancel-button").on("click", function(){ + $('#user-create').hide(); + }); + + + $("#user-create").on("submit",function(){ + //nothing + }); + + /** + * call successFn on success with passing user object coming from cookie + */ + userLogged=function(successFn,notLoggedFn) { + // call restServices/redbackServices/loginService/isLogged to know + // if a session exists and check the cookie + $.log("userLogged"); + var userLogged = true; + $.ajax("restServices/redbackServices/loginService/isLogged", { + type: "GET", + success: function(data) { + var user = data ? mapUser(data):null; + window.user=user; + if(user){ + reccordLoginCookie(user); + } + $.log("userLogged:"+(user!=null)); + if (successFn){ + successFn(user ? user:null); + } + if(!user){ + if(notLoggedFn){ + notLoggedFn(); + } + } + } + }); + } + + Operation=function(name) { + this.name=ko.observable(name); + } + + /** + * @param data Operation response from redback rest api + */ + mapOperation=function(data) { + return new Operation(data.name,null); + } + + Permission=function(name,operation,resource) { + this.name=ko.observable(name); + this.operation=ko.observable(operation); + this.resource=ko.observable(resource); + } + + /** + * @param data Permission response from redback rest api + */ + mapPermission=function(data) { + return new Permission(data.name, + data.operation?mapOperation(data.operation):null, + data.resource?mapResource(data.resource):null); + } + + Resource=function(identifier,pattern) { + this.identifier=ko.observable(identifier); + this.pattern=ko.observable(pattern); + } + + /** + * @param data Resource response from redback rest api + */ + mapResource=function(data) { + return new Resource(data.identifier,data.pattern); + } + + //--------------------------------------- + // register part + //--------------------------------------- + + /** + * open the register modal box + */ + registerBox=function(){ + var modalRegister=$("#modal-register"); + if (window.modalRegisterWindow==null) { + window.modalRegisterWindow = modalRegister.modal({backdrop:'static',show:false}); + window.modalRegisterWindow.bind('hidden', function () { + $("#modal-register-err-message").hide(); + }) + } + window.modalRegisterWindow.modal('show'); + $("#user-register-form").validate({ + showErrors: function(validator, errorMap, errorList) { + customShowError("#user-register-form",validator,errorMap,errorMap); + } + }); + modalRegister.delegate("#modal-register-ok", "click keydown keypress", function(e) { + e.preventDefault(); + register(); + }); + //$("#modal-register").focus(); + } + + UserRegistrationRequest=function(user,applicationUrl){ + this.user=user; + this.applicationUrl=applicationUrl; + } + + /** + * validate the register form and call REST service + */ + register=function(){ + + $.log("redback.js#register"); + var valid = $("#user-register-form").valid(); + if (!valid) { + return; + } + clearUserMessages(); + $("#modal-register-ok").attr("disabled","disabled"); + + $('#modal-register-footer').append(smallSpinnerImg()); + + $.ajax({ + url: "restServices/archivaServices/archivaAdministrationService/applicationUrl", + type: "GET", + dataType: 'text', + success: function(data){ + $.log("applicationUrl ok:"+data); + + var user = { + username: $("#user-register-form-username").val(), + fullName: $("#user-register-form-fullname").val(), + email: $("#user-register-form-email").val() + }; + + var userRegistrationRequest=new UserRegistrationRequest(user,data); + $.ajax({ + url: 'restServices/redbackServices/userService/registerUser', + data: JSON.stringify(userRegistrationRequest), + type: 'POST', + contentType: "application/json", + success: function(result){ + var registered = false; + if (result == "-1") { + registered = false; + } else { + registered = true; + } + + if (registered == true) { + window.modalRegisterWindow.modal('hide'); + $("#register-link").hide(); + // FIXME i18n + displaySuccessMessage("registered your key has been sent"); + } + }, + complete: function(){ + $("#modal-register-ok").removeAttr("disabled"); + removeSmallSpinnerImg(); + }, + error: function(result) { + window.modalRegisterWindow.modal('hide'); + } + }); + } + }); + + } + + /** + * validate a registration key and go to change password key + * @param key + */ + validateKey=function(key,registration) { + // FIXME spinner display + $.ajax({ + url: 'restServices/redbackServices/userService/validateKey/'+key, + type: 'GET', + success: function(result){ + window.redbackModel.key=key; + $.log("validateKey#sucess"); + changePasswordBox(false,registration?registration:true,null); + }, + complete: function(){ + // hide spinner + }, + error: function(result) { + $.log("validateKey#error"); + } + }) + } + +});
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/redback/roles.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/redback/roles.js new file mode 100644 index 000000000..5b6d7cb4c --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/redback/roles.js @@ -0,0 +1,387 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +define("redback.roles",["jquery","utils","i18n","jquery.validate","knockout","knockout.simpleGrid"], +function(jquery,utils,i18n,jqueryValidate,ko,koSimpleGrid) { + + Role = function(name,description,assignable,childRoleNames,parentRoleNames,users,parentsRolesUsers,permissions,otherUsers){ + + var self=this; + + this.name = ko.observable(name); + this.name.subscribe(function(newValue){self.modified(true)}); + + this.description = ko.observable(description); + this.description.subscribe(function(newValue){self.modified(true)}); + + this.assignable = ko.observable(assignable); + this.assignable.subscribe(function(newValue){self.modified(true)}); + + this.childRoleNames = ko.observableArray(childRoleNames);//read only + this.childRoleNames.subscribe(function(newValue){self.modified(true)}); + + this.parentRoleNames = ko.observableArray(parentRoleNames);//read only + this.parentRoleNames.subscribe(function(newValue){self.modified(true)}); + + this.users = ko.observableArray(users?users:new Array()); + this.users.subscribe(function(newValue){self.modified(true)}); + + this.parentsRolesUsers = ko.observableArray(parentsRolesUsers);//read only + this.parentsRolesUsers.subscribe(function(newValue){self.modified(true)}); + + this.permissions = ko.observableArray(permissions);//read only + this.permissions.subscribe(function(newValue){self.modified(true)}); + + // when editing a role other users not assign to this role are populated + this.otherUsers = ko.observableArray(otherUsers?otherUsers:new Array()); + this.otherUsers.subscribe(function(newValue){self.modified(true)}); + + this.removedUsers= ko.observableArray(new Array()); + this.removedUsers.subscribe(function(newValue){self.modified(true)}); + + this.modified=ko.observable(false); + + this.usersModified=ko.observable(false); + + this.updateDescription=function(){ + var url = "restServices/redbackServices/roleManagementService/updateRoleDescription?"; + var roleName = this.name(); + url += "roleName="+encodeURIComponent(roleName); + url += "&roleDescription="+encodeURIComponent(this.description()); + $.ajax(url, + { + type: "GET", + dataType: 'json', + success: function(data) { + clearUserMessages(); + displaySuccessMessage($.i18n.prop("role.updated",roleName)); + }, + error: function(data){ + clearUserMessages(); + displayErrorMessage("error updating role description"); + } + } + ); + } + + this.updateUsers=function(){ + var url = "restServices/redbackServices/roleManagementService/updateRoleUsers"; + $.ajax(url, + { + type: "POST", + dataType: 'json', + contentType: 'application/json', + data: ko.toJSON(self), + success: function(data) { + clearUserMessages(); + displaySuccessMessage($.i18n.prop("role.users.updated",self.name())); + self.usersModified(false); + self.modified(false); + }, + error: function(data){ + clearUserMessages(); + displayErrorMessage("error updating users role"); + } + } + ); + } + + } + + /** + * view model used for roles grid + */ + RolesViewModel=function() { + this.roles = ko.observableArray([]); + + var self = this; + + + this.gridViewModel = new ko.simpleGrid.viewModel({ + data: this.roles, + viewModel: this, + columns: [ + { + headerText: $.i18n.prop('name'), + rowText: "name" + }, + { + headerText: $.i18n.prop('description'), + rowText: "description" + } + ], + pageSize: 10 + }); + + editRole=function(role){ + var mainContent = $("#main-content"); + mainContent.find("#roles-view-tabs-content #role-edit").html(mediumSpinnerImg()); + // load missing attributes + $.ajax("restServices/redbackServices/roleManagementService/getRole/"+encodeURIComponent(role.name()), + { + type: "GET", + dataType: 'json', + success: function(data) { + var mappedRole = mapRole(data); + role.parentRoleNames(mappedRole.parentRoleNames()); + role.parentsRolesUsers(mappedRole.parentsRolesUsers()); + role.users(mappedRole.users()); + role.otherUsers(mappedRole.otherUsers()); + role.modified(false); + var viewModel = new RoleViewModel(role); + ko.applyBindings(viewModel,mainContent.find("#roles-view-tabs-content #role-edit").get(0)); + activateRoleEditTab(); + mainContent.find("#role-view-users").tabs("show"); + mainContent.find("#role-edit-users-tabs-content #role-view-users").addClass("active"); + mainContent.find("#role-edit").collapse("show"); + } + } + ); + } + + this.bulkSave=function(){ + $.log("bulkSave"); + return getModifiedRoles().length>0; + } + + getModifiedRoles=function(){ + var prx = $.grep(self.roles(), + function (role,i) { + return role.modified()||role.usersModified(); + }); + return prx; + } + + updateModifiedRoles=function(){ + var modifiedRoles = getModifiedRoles(); + $.log("modifiedRoles:"+modifiedRoles); + openDialogConfirm(function(){ + for(i=0;i<modifiedRoles.length;i++){ + var modifiedRole=modifiedRoles[i]; + if (modifiedRole.modified()){ + modifiedRole.updateDescription(); + modifiedRole.modified(false); + } + if (modifiedRole.usersModified()){ + modifiedRole.updateUsers(); + modifiedRole.usersModified(false); + } + } + closeDialogConfirm(); + }, + $.i18n.prop('ok'), + $.i18n.prop('cancel'), + $.i18n.prop('roles.bulk.save.confirm.title'), + $.i18n.prop('roles.bulk.save.confirm',modifiedRoles.length)); + + + } + + updateRole=function(modifiedRole){ + if (modifiedRole.modified()){ + modifiedRole.updateDescription(); + modifiedRole.modified(false); + } + if (modifiedRole.usersModified()){ + modifiedRole.updateUsers(); + modifiedRole.usersModified(false); + } + } + + } + + displayRolesGrid = function(){ + screenChange(); + var mainContent = $("#main-content"); + mainContent.html(mediumSpinnerImg()); + + $.ajax("restServices/redbackServices/roleManagementService/allRoles", { + type: "GET", + dataType: 'json', + success: function(data) { + var mappedRoles = $.map(data, function(item) { + return mapRole(item); + }); + var rolesViewModel = new RolesViewModel(); + rolesViewModel.roles(mappedRoles); + mainContent.html($("#rolesTabs").tmpl()); + ko.applyBindings(rolesViewModel,mainContent.find("#roles-view").get(0)); + mainContent.find("#roles-view-tabs #roles-view-tabs-a-roles-grid").tab("show"); + activateRolesGridTab(); + removeMediumSpinnerImg(mainContent); + } + } + ); + + + } + + RoleViewModel=function(role){ + selectedOtherUsers= ko.observableArray(); + selectedUsers= ko.observableArray(); + currentRole=role; + var self=this; + addUser=function(){ + $.log("addUser"); + var removed = currentRole.otherUsers.removeAll(selectedOtherUsers()); + for (var i = 0; i < removed.length; i++) { + $.log("add user:"+removed[i].username()); + currentRole.users.push(removed[i]); + role.usersModified(true); + } + selectedOtherUsers([]); + $("#role-collapse" ).removeClass("in"); + $("#role-users-collapse" ).addClass("in"); + activateRoleUsersEditTab(); + } + + removeUser=function(){ + $.log("removeUser"); + var added = currentRole.users.removeAll(selectedUsers()); + for (var i = 0; i < added.length; i++) { + currentRole.otherUsers.push(added[i]); + currentRole.removedUsers.push(added[i]); + role.usersModified(true); + } + selectedUsers([]); + $("#role-collapse" ).removeClass("in"); + $("#role-users-collapse" ).addClass("in"); + activateRoleUsersEditTab(); + } + + saveRoleDescription=function(){ + currentRole.updateDescription(); + } + saveUsers=function(){ + currentRole.updateUsers(); + } + + updateMode=function(){ + var mainContent = $("#main-content"); + mainContent.find("#role-list-users").hide(); + mainContent.find("#role-edit-users").show(); + } + viewMode=function(){ + var mainContent = $("#main-content"); + mainContent.find("#role-edit-users").hide(); + mainContent.find("#role-list-users").show(); + } + } + + /** + * @param data Role response from redback rest api + */ + mapRole=function(data) { + // olamy this mapping has issues when fields are array or not + //return ko.mapping.fromJS(data); + // name, description, assignable,childRoleNames,parentRoleNames,users,parentsRolesUsers,permissions + //$.log("mapRole:"+data.name+":"); + var childRoleNames = mapStringArray(data.childRoleNames); + var parentRoleNames = mapStringArray(data.parentRoleNames); + var users = data.users ? $.isArray(data.users) ? $.map(data.users, function(item) { + return mapUser(item); + }):new Array(mapUser(data.users)):null; + + var parentsRolesUsers = data.parentsRolesUsers ? $.isArray(data.parentsRolesUsers)? $.map(data.parentsRolesUsers, function(item) { + return mapUser(item); + }):new Array(mapUser(data.parentsRolesUsers)):null; + + var permissions = data.permissions? $.isArray(data.permissions) ? $.map(data.permissions, function(item){ + return mapPermission(item); + }): new Array(mapPermission(data.permissions)) :null; + + var otherUsers = data.otherUsers ? $.isArray(data.otherUsers)? $.map(data.otherUsers, function(item) { + return mapUser(item); + }):new Array(mapUser(data.otherUsers)):null; + + return new Role(data.name, data.description?data.description:"",data.assignable,childRoleNames,parentRoleNames,users,parentsRolesUsers,permissions,otherUsers); + } + + activateRolesGridTab=function(){ + $("#main-content").find("#roles-view-tabs").find("li").removeClass("active"); + $("#main-content").find("#roles-view-tabs-content").find("div").removeClass("active"); + // activate roles grid tab + $("#main-content").find("#roles-view-tabs-content").find("#roles-view").addClass("active"); + $("#main-content").find("#roles-view-tabs-li-roles-grid").addClass("active"); + } + + activateRoleEditTab=function(){ + $("#main-content").find("#roles-view-tabs").find("li").removeClass("active"); + $("#main-content").find("#roles-view-tabs-content").find("div").removeClass("active"); + // activate role edit tab + $("#main-content").find("#roles-view-tabs-content").find("#role-edit").addClass("active"); + $("#roles-view-tabs-li-roles-edit").addClass("active"); + } + + activateRoleUsersListTab=function(){ + $("#main-content").find("#role-edit-users-li").removeClass("active"); + $("#main-content").find("#role-edit-users").removeClass("active"); + // activate roles grid tab + $("#main-content").find("#role-view-users-li").addClass("active"); + $("#main-content").find("#role-view-users").addClass("active"); + } + + activateRoleUsersEditTab=function(){ + $("#main-content").find("#role-view-users-li").removeClass("active"); + $("#main-content").find("#role-view-users").removeClass("active"); + // activate role edit tab + $("#main-content").find("#role-edit-users").addClass("active"); + $("#role-edit-users-li").addClass("active"); + } + + ApplicationRoles = function(name,description,globalRoles,roleTemplates,resources){ + //private String name; + this.name = ko.observable(name); + //private String description; + this.description = description? ko.observable(description):""; + //private Collection<String> globalRoles; + this.globalRoles = ko.observableArray(globalRoles); + //private Collection<RoleTemplate> roleTemplates; + this.roleTemplates = ko.observableArray(roleTemplates); + //private Collection<String> resources; + this.resources = ko.observableArray(resources); + } + + mapApplicationRoles=function(data){ + var roleTemplates = data.roleTemplates ? $.isArray(data.roleTemplates) ? $.map(data.roleTemplates, function(item) { + return mapRoleTemplate(item); + }):new Array(mapRoleTemplate(data.roleTemplates)):null; + + return new ApplicationRoles(data.name,data.description,mapStringArray(data.globalRoles),roleTemplates,mapStringArray(data.resources)); + } + + RoleTemplate = function(id,namePrefix,delimiter,description,resource,roles){ + //private String id; + this.id = ko.observable(id); + //private String namePrefix; + this.namePrefix = ko.observable(namePrefix); + //private String delimiter = " - "; + this.delimiter = ko.observable(delimiter); + //private String description; + this.description = description? ko.observable(description):""; + //private String resource; + this.resource = ko.observable(resource); + //private List<String> roles; + this.roles = ko.observableArray(roles); + } + + mapRoleTemplate = function(data){ + return new RoleTemplate(data.id,data.namePrefix,data.delimiter,data.description,mapStringArray(data.roles)); + } + +});
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/redback/user.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/redback/user.js new file mode 100644 index 000000000..f7d4bf2ee --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/redback/user.js @@ -0,0 +1,835 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +define("redback.user",["jquery","utils","i18n","jquery.validate","knockout","knockout.simpleGrid","purl"], +function(jquery,utils,i18n,jqueryValidate,ko,koSimpleGrid,purl) { + + /** + * object model for user with some function to create/update/delete users + * @param username + * @param password + * @param confirmPassword + * @param fullName + * @param email + * @param permanent + * @param validated + * @param timestampAccountCreation + * @param timestampLastLogin + * @param timestampLastPasswordChange + * @param locked + * @param passwordChangeRequired + * @param ownerViewModel + * @param readOnly + * @param uuserManagerId + */ + User=function(username, password, confirmPassword,fullName,email,permanent,validated,timestampAccountCreation, + timestampLastLogin,timestampLastPasswordChange,locked,passwordChangeRequired,ownerViewModel,readOnly,userManagerId) { + var self=this; + // Potentially Editable Field. + this.username = ko.observable(username); + this.username.subscribe(function(newValue){self.modified(true)}); + // Editable Fields. + this.password = ko.observable(password); + this.password.subscribe(function(newValue){self.modified(true)}); + + this.confirmPassword = ko.observable(confirmPassword); + this.confirmPassword.subscribe(function(newValue){self.modified(true)}); + + this.fullName = ko.observable(fullName); + this.fullName.subscribe(function(newValue){self.modified(true)}); + + this.email = ko.observable(email); + this.email.subscribe(function(newValue){self.modified(true)}); + + this.permanent = ko.observable(permanent); + this.permanent.subscribe(function(newValue){self.modified(true)}); + + this.validated = ko.observable(validated); + this.validated.subscribe(function(newValue){self.modified(true)}); + + // Display Only Fields. + this.timestampAccountCreation = ko.observable(timestampAccountCreation); + this.timestampLastLogin = ko.observable(timestampLastLogin); + this.timestampLastPasswordChange = ko.observable(timestampLastPasswordChange); + // admin only + this.locked = ko.observable(locked); + this.locked.subscribe(function(newValue){self.modified(true)}); + + this.passwordChangeRequired = ko.observable(passwordChangeRequired); + this.passwordChangeRequired.subscribe(function(newValue){self.modified(true)}); + + this.assignedRoles = ko.observableArray(new Array()); + this.assignedRoles.subscribe(function(newValue){self.modified(true)}); + + this.modified=ko.observable(false); + + this.readOnly=readOnly; + + this.userManagerId=userManagerId; + + this.rememberme=ko.observable(false); + + this.logged=false; + + this.remove = function() { + if (ownerViewModel) { + ownerViewModel.users.destroy(this); + } + }; + this.create = function(successFnCallback) { + if (username == 'admin') { + this.createAdmin(); + } else { + this.createUser(successFnCallback); + } + }; + this.createUser = function(successFnCallback) { + $.log("user#createUser"); + var valid = $("#user-create").valid(); + if (!valid) { + return; + } + var currentUser = this; + $.ajax("restServices/redbackServices/userService/createUser", { + data: ko.toJSON(this), + contentType: 'application/json', + type: "POST", + dataType: 'json', + success: function(result) { + var created = result; + if (created == true) { + displaySuccessMessage( $.i18n.prop("user.created",currentUser.username())); + if (successFnCallback){ + successFnCallback(currentUser); + } + clearForm("#main-content #user-create"); + $("#main-content").find("#user-create").hide(); + activateUsersGridTab(); + return this; + } else { + displayErrorMessage("user cannot created"); + } + } + }); + }; + + this.createAdmin = function(succesCallbackFn,errorCallbackFn) { + $.log("user.js#createAdmin"); + var valid = $("#user-create").valid(); + $.log("create admin"); + if (!valid) { + return; + } + var currentAdminUser = this; + $.ajax("restServices/redbackServices/userService/createAdminUser", { + data: ko.toJSON(this), + contentType: 'application/json', + type: "POST", + dataType: 'json', + success: function(result) { + var created = result; + if (created == true) { + displaySuccessMessage( $.i18n.prop("user.admin.created")); + var onSuccessCall=function(){ + reccordLoginCookie(currentAdminUser); + window.archivaModel.adminExists=true; + screenChange(); + checkCreateAdminLink(); + checkSecurityLinks(); + } + loginCall(currentAdminUser.username(), currentAdminUser.password(),false,onSuccessCall); + if(succesCallbackFn){ + succesCallbackFn(); + } + return this; + } else { + displayErrorMessage("admin user not created"); + } + }, + error: function(data){ + if(errorCallbackFn){ + errorCallbackFn(); + } + } + }); + }; + + + this.update=function(){ + var currentUser = this; + $.ajax("restServices/redbackServices/userService/updateUser", { + data: ko.toJSON(this), + contentType: 'application/json', + type: "POST", + dataType: 'json', + success: function(result) { + var updated = result; + if (updated == true) { + clearUserMessages(); + displaySuccessMessage($.i18n.prop("user.updated",currentUser.username())); + $("#main-content").find("#users-view-tabs-li-user-edit").find("a").html($.i18n.prop("add")); + clearForm("#main-content #user-create"); + activateUsersGridTab(); + return this; + } else { + displayErrorMessage("user cannot be updated"); + } + } + }); + } + + this.save=function(){ + $.log("user.save create:"+window.redbackModel.createUser); + if (window.redbackModel.createUser==true){ + var valid = $("#main-content").find("#user-create").valid(); + + if (valid==false) { + $.log("user#save valid:false"); + return; + } else { + $.log("user#save valid:true"); + return this.create(); + } + } else { + return this.update(); + } + } + + this.updateAssignedRoles=function(){ + $.log("user#updateAssignedRoles"); + var curUser = this; + clearUserMessages(); + $.ajax("restServices/redbackServices/roleManagementService/updateUserRoles", { + data: ko.toJSON(this), + contentType: 'application/json', + type: "POST", + dataType: 'json', + success: function(result) { + displaySuccessMessage($.i18n.prop("user.roles.updated",curUser.username())); + } + }); + } + + this.lock=function(){ + this.locked(true); + var curUser = this; + clearUserMessages(); + $.ajax("restServices/redbackServices/userService/lockUser/"+encodeURIComponent(curUser.username()), { + type: "GET", + success: function(result) { + displaySuccessMessage($.i18n.prop("user.locked",curUser.username())); + curUser.modified(false); + } + }); + } + + this.unlock=function(){ + this.locked(false); + var curUser = this; + clearUserMessages(); + $.ajax("restServices/redbackServices/userService/unlockUser/"+encodeURIComponent(curUser.username()), { + type: "GET", + success: function(result) { + displaySuccessMessage($.i18n.prop("user.unlocked",curUser.username())); + curUser.modified(false); + } + }); + } + + // value is boolean + this.changePasswordChangeRequired=function(value){ + this.passwordChangeRequired(value); + var curUser = this; + var url = "restServices/redbackServices/userService/passwordChangeRequired/"+encodeURIComponent(curUser.username()); + if (value==false){ + url = "restServices/redbackServices/userService/passwordChangeNotRequired/"+encodeURIComponent(curUser.username()); + } + $.ajax(url, { + type: "GET", + success: function(result) { + displaySuccessMessage($.i18n.prop("user.passwordChangeRequired.updated",curUser.username(),value)); + curUser.modified(false); + } + }); + }; + + } + + /** + * view for admin user creation + */ + AdminUserViewModel=function() { + this.user = new User("admin","","", "the administrator"); + var self=this; + saveUser=function(){ + if(! $("#user-create" ).valid() ) { + return; + } + self.user.createAdmin(function(){ + // go to search when admin created + window.sammyArchivaApplication.setLocation("#search"); + } + ); + } + } + + /** + * open a modal box to create admin user + */ + adminCreateBox=function() { + var mainContent=$("#main-content"); + + $.ajax("restServices/redbackServices/userService/isAdminUserExists", { + type: "GET", + dataType: 'json', + success: function(data) { + var adminExists = data; + window.archivaModel.adminExists=adminExists; + if (adminExists == false) { + + window.redbackModel.createUser=true; + mainContent.attr("data-bind",'template: {name:"redback/user-edit-tmpl",data: user}'); + var viewModel = new AdminUserViewModel(); + ko.applyBindings(viewModel,mainContent.get(0)); + $.log("adminCreateBox"); + $("#user-create").validate({ + rules: { + confirmPassword: { + equalTo: "#password" + } + }, + showErrors: function(validator, errorMap, errorList) { + customShowError("#main-content #user-create",validator,errorMap,errorMap); + } + + }); + // desactivate roles pill when adding user + $("#edit_user_details_pills_headers").hide(); + + } else { + window.sammyArchivaApplication.setLocation("#search"); + } + + } + }); + } + + /** + * open a modal box for login + */ + loginBox=function(){ + + if (window.modalLoginWindow!=null){ + window.modalLoginWindow=null; + } + if (window.modalLoginWindow==null) { + window.modalLoginWindow = $("#modal-login").modal(); + window.modalLoginWindow.on('hidden', function () { + $("#modal-login-err-message").hide(); + removeValidationErrorMessages("#user-login-form"); + }); + // focus on user name + window.modalLoginWindow.on('shown', function (e) { + $("#user-login-form-username" ).focus(); + }); + window.modalLoginWindow.keypress( function (event) { + if (event.which==13){ + $("#modal-login-ok" ).trigger("click"); + } + }); + } + + var user=getUserFromLoginCookie(); + if(user){ + $.log("found user in cookie rememberme:"+(user.rememberme())); + if(user.rememberme()){ + $("#user-login-form-username" ).val(user.username()); + $("#user-login-form-password" ).val(user.password()); + $("#user-login-form-rememberme" ).attr("checked","true"); + } + } else { + $.log("user not in cookie"); + } + + var rememberMe=window.redbackRuntimeConfiguration.findPropertyValue('security.rememberme.enabled'); + $.log("rememberMe:"+rememberMe); + if (rememberMe=='false'){ + $("#user-login-form-rememberme-label" ).hide(); + $("#user-login-form-rememberme" ).attr("disabled","true"); + if($("#user-login-form-rememberme" ).get(0 ).checked){ + $("#user-login-form-rememberme" ).get(0 ).checked=false; + } + $("#user-login-form-username" ).val(""); + $("#user-login-form-password" ).val(""); + } + + var userLoginForm = $("#user-login-form"); + + userLoginForm.validate({ + showErrors: function(validator, errorMap, errorList) { + customShowError("#user-login-form",validator,errorMap,errorMap); + } + }); + $("#modal-login-ok").on("click", function(e) { + e.preventDefault(); + login(); + }); + + $("#modal-login-password-reset").on("click", function(e) { + e.preventDefault(); + $.log("password reset"); + passwordReset(); + }); + + } + + + /** + * callback success function on rest login call. + * modal close and hide/show some links (login,logout,register...) + * @param result + */ + var successLoginCallbackFn=function(result){ + + var logged = false; + if (result == null) { + logged = false; + } else { + if (result.username) { + logged = true; + } + } + if (logged == true) { + var user = mapUser(result); + + if (user.passwordChangeRequired()==true){ + changePasswordBox(true,false,user); + return; + } + // not really needed as an exception is returned but "ceintures et bretelles" as we say in French :-) + if (user.locked()==true){ + $.log("user locked"); + displayErrorMessage($.i18n.prop("account.locked")); + return; + } + + // FIXME check validated + user.rememberme(window.redbackModel.rememberme); + if(user.rememberme()){ + user.password(window.redbackModel.password); + } + $.log("user.rememberme:"+(user.rememberme())); + reccordLoginCookie(user); + window.user=user; + $("#login-link").hide(); + $("#logout-link").show(); + $("#register-link").hide(); + $("#change-password-link").show(); + if (window.modalLoginWindow){ + window.modalLoginWindow.modal('hide'); + } + clearForm("#user-login-form"); + decorateMenuWithKarma(user); + + return; + } + var modalLoginErrMsg=$("#modal-login-err-message"); + modalLoginErrMsg.html($.i18n.prop("incorrect.username.password")); + modalLoginErrMsg.show(); + } + + /** + * callback error function on rest login call. display error message + * @param result + */ + var errorLoginCallbackFn= function(result) { + var obj = jQuery.parseJSON(result.responseText); + displayRedbackError(obj,"modal-login-err-message"); + $("#modal-login-err-message").show(); + } + + /** + * callback complate function on rest login call. remove spinner from modal login box + * @param result + */ + var completeLoginCallbackFn=function(){ + $("#modal-login-ok").button("reset"); + $("#small-spinner").remove(); + // force current screen reload to consider user karma + window.sammyArchivaApplication.refresh(); + } + + resetPasswordForm=function(key){ + $.log("resetPasswordForm:"+key); + changePasswordBox(null,false,null,function(){ + $.log("ok chgt pwd") + $.log("user.js#changePassword"); + var valid = $("#password-change-form").valid(); + if (valid==false) { + return; + } + var url = 'restServices/redbackServices/passwordService/changePasswordWithKey?'; + url += "password="+$("#passwordChangeFormNewPassword").val(); + url += "&passwordConfirmation="+$("#passwordChangeFormNewPasswordConfirm").val(); + url += "&key="+key; + $.log("url:"+url); + + $.ajax({ + url: url, + success: function(result){ + $.log("changePassword#success result:"+result); + var user = mapUser(result); + if (user) { + window.modalChangePasswordBox.modal('hide'); + displaySuccessMessage($.i18n.prop('change.password.success.section.title')); + } else { + displayErrorMessage("issue appended"); + } + window.modalChangePasswordBox.modal('hide'); + var curHash = getUrlHash(); + var url = $.url(window.location); + var newLocation=url.attr("path"); + var requestLang=url.param("request_lang"); + if(requestLang){ + newLocation+="?request_lang="+requestLang; + } + if(curHash){ + newLocation+="#"+curHash; + }else{ + newLocation+="#search"; + } + window.location=newLocation; + }, + statusCode: { + 500: function(data){ + $("#modal-password-change-err-message" ).empty(); + displayRestError($.parseJSON(data.responseText),"modal-password-change-err-message"); + $("#modal-password-change-err-message" ).show(); + } + } + }); + + } + ); + } + + ResetPasswordRequest=function(username,applicationUrl){ + this.username=username; + this.applicationUrl=applicationUrl; + } + + passwordReset=function(){ + var userLoginFormUsername=$("#user-login-form-username" ); + var username = userLoginFormUsername.val(); + if(username.trim().length<1){ + var errorList=[{ + message: $.i18n.prop("username.cannot.be.empty"), + element: userLoginFormUsername.get(0) + }]; + customShowError("#user-login-form", null, null, errorList); + return; + } + + if (window.modalLoginWindow){ + window.modalLoginWindow.modal('hide'); + } + $("#user-messages" ).html(mediumSpinnerImg()); + + $.ajax({ + url: "restServices/archivaServices/archivaAdministrationService/applicationUrl", + type: "GET", + dataType: 'text', + success: function(data){ + + $.ajax("restServices/redbackServices/userService/resetPassword", { + type: "POST", + data: JSON.stringify(new ResetPasswordRequest(username,data)), + contentType: "application/json", + success: function(result) { + clearUserMessages(); + displayInfoMessage($.i18n.prop("password.reset.success")); + } + }); + } + }); + } + + /** + * validate login box before ajax call + */ + login=function(){ + $.log("user.js#login"); + + $("#modal-login-err-message").empty(); + + var valid = $("#user-login-form").valid(); + if (!valid) { + return; + } + $("#modal-login-ok").button("loading"); + + $('#modal-login-footer').append(smallSpinnerImg()); + + var rememberme=($("#user-login-form-rememberme" ).attr('checked')=='checked'); + window.redbackModel.rememberme=rememberme; + window.redbackModel.password=$("#user-login-form-password").val(); + + loginCall($("#user-login-form-username").val(),window.redbackModel.password,rememberme + ,successLoginCallbackFn,errorLoginCallbackFn,completeLoginCallbackFn); + + } + + /** + * call REST method for login + * @param username + * @param password + * @param rememberme + * @param successCallbackFn + * @param errorCallbackFn + * @param completeCallbackFn + */ + loginCall=function(username,password,rememberme,successCallbackFn, errorCallbackFn, completeCallbackFn) { + var url = 'restServices/redbackServices/loginService/logIn'; + + $.ajax({ + url: url, + type: 'POST', + contentType: 'application/json', + data: JSON.stringify({username:username,password:password}), + success: successCallbackFn, + error: errorCallbackFn, + complete: completeCallbackFn + }); + + } + + /** + * + * @param previousPassword display and validate previous password text field + * @param registration are we in registration mode ? + */ + changePasswordBox=function(previousPassword,registration,user,okFn){ + $.log("changePasswordBox"); + screenChange(); + $.log("changePasswordBox previousPassword:"+previousPassword+",registration:"+registration+",user:"+user); + if (previousPassword==true){ + $("#password-change-form-current-password-div").show(); + $("#password-change-form-current-password").addClass("required"); + }else{ + $("#password-change-form-current-password-div").hide(); + $("#password-change-form-current-password").removeClass("required"); + } + if (window.modalChangePasswordBox == null) { + window.modalChangePasswordBox = $("#modal-password-change").modal({backdrop:'static',show:false}); + window.modalChangePasswordBox.bind('hidden', function () { + $("#modal-password-change-err-message").hide(); + }) + $("#modal-password-change").delegate("#modal-change-password-ok", "click keydown keypress", function(e) { + e.preventDefault(); + if ( $.isFunction(okFn)){ + okFn(); + } else { + changePassword(previousPassword,registration,user); + } + }); + } + window.modalChangePasswordBox.modal('show'); + $("#password-change-form").validate({ + rules: { + passwordChangeFormNewPasswordConfirm : { + equalTo: "#passwordChangeFormNewPassword" + } + }, + showErrors: function(validator, errorMap, errorList) { + customShowError("#password-change-form",validator,errorMap,errorMap); + } + }); + + + $("#modal-password-change").focus(); + } + + EditUserDetailViewModel=function(user){ + this.user=user; + } + + /** + * display modal box for updating current user details + */ + editUserDetailsBox=function(){ + clearUserMessages(); + $("#modal-user-edit-err-message").hide(); + $("#modal-user-edit-err-message").empty(); + if (window.modalEditUserBox == null) { + window.modalEditUserBox = $("#modal-user-edit").modal({backdrop:'static',show:false}); + window.modalEditUserBox.bind('hidden', function () { + $("#modal-user-edit-err-message").hide(); + }) + $("#modal-user-edit").find("#modal-user-edit-ok").on( "click keydown keypress", function(e) { + e.preventDefault(); + $.log("user.js#editUserDetailsBox"); + var valid = $("#user-edit-form").valid(); + if (!valid) { + return; + } + var user = { + username:currentUser.username, + fullName:$("#modal-user-edit").find("#fullname").val(), + email:$("#modal-user-edit").find("#email").val(), + previousPassword:$("#modal-user-edit").find("#userEditFormCurrentPassword").val(), + password:$("#modal-user-edit").find("#userEditFormNewPassword").val(), + confirmPassword:$("#modal-user-edit").find("#userEditFormNewPasswordConfirm").val() + }; + editUserDetails(user); + }); + } + var currentUser = getUserFromLoginCookie(); + /*$("#modal-user-edit").find("#username").html(currentUser.username); + $("#modal-user-edit").find("#fullname").val(currentUser.fullName); + $("#modal-user-edit").find("#email").val(currentUser.email);*/ + + $("#modal-user-edit-content" ).attr("data-bind",'template: {name:"modal-user-edit-tmpl"}'); + + var editUserDetailViewModel=new EditUserDetailViewModel(currentUser); + ko.applyBindings(editUserDetailViewModel,$("#modal-user-edit-content").get(0)); + + if(currentUser.readOnly){ + $("#modal-user-edit-footer" ).hide(); + } + + window.modalEditUserBox.modal('show'); + $("#user-edit-form").validate({ + rules: { + userEditFormNewPasswordConfirm : { + equalTo: "#userEditFormNewPassword" + } + }, + showErrors: function(validator, errorMap, errorList) { + customShowError("#user-edit-form",validator,errorMap,errorMap); + } + }); + + + $("#modal-user-edit").focus(); + } + + /** + * REST call to update current user + * @param user + */ + editUserDetails=function(user){ + $("#modal-user-edit-err-message").empty(); + $.ajax("restServices/redbackServices/userService/updateMe", { + data: ko.toJSON(user), + contentType: 'application/json', + type: "POST", + dataType: 'json', + success: function(result) { + var created = result; + if (created == true) { + displaySuccessMessage( $.i18n.prop("user.details.updated")); + window.modalEditUserBox.modal('hide'); + reccordLoginCookie(user); + clearForm("#user-edit-form"); + return this; + } else { + displayErrorMessage("details cannot be updated","modal-user-edit-err-message"); + } + }, + error: function(result) { + var obj = jQuery.parseJSON(result.responseText); + $("#modal-user-edit-err-message").show(); + displayRedbackError(obj,"modal-user-edit-err-message"); + } + }); + + } + + + /** + * + * @param previousPassword display and validate previous password text field + * @param registration are we in registration mode ? if yes the user will be logged + */ + changePassword=function(previousPassword,registration,user){ + $.log("user.js#changePassword"); + var valid = $("#password-change-form").valid(); + if (valid==false) { + return; + } + $('#modal-password-change-footer').append(smallSpinnerImg()); + + if (registration==true) { + var url = 'restServices/redbackServices/passwordService/changePasswordWithKey?'; + url += "password="+$("#passwordChangeFormNewPassword").val(); + url += "&passwordConfirmation="+$("#passwordChangeFormNewPasswordConfirm").val(); + url += "&key="+window.redbackModel.key; + } else { + var url = 'restServices/redbackServices/passwordService/changePassword?'; + url += "password="+$("#passwordChangeFormNewPassword").val(); + url += "&passwordConfirmation="+$("#passwordChangeFormNewPasswordConfirm").val(); + url += "&previousPassword="+$("#password-change-form-current-password").val(); + url += "&userName="+user.username(); + } + + $.ajax({ + url: url, + success: function(result){ + $.log("changePassword#success result:"+result); + var user = mapUser(result); + if (user) { + window.modalChangePasswordBox.modal('hide'); + if (registration==true) { + $.log("changePassword#sucess,registration:"+registration); + displaySuccessMessage($.i18n.prop('change.password.success.section.title')) + loginCall(user.username(), $("#passwordChangeFormNewPassword").val(),true,successLoginCallbackFn, + function(data){ + displayRestError(data,"modal-password-change-content"); + } + ,function(){ + window.modalChangePasswordBox.modal('hide'); + window.location=window.location.toString().substringBeforeFirst("?"); + window.sammyArchivaApplication.setLocation("#search"); + }); + } else { + displaySuccessMessage($.i18n.prop('change.password.success.section.title')); + } + } else { + displayErrorMessage("issue appended"); + } + window.modalChangePasswordBox.modal('hide'); + } + }); + + //$.urlParam('validateMe') + // for success i18n key change.password.success.section.title + } + + /** + * @param data User response from redback rest api + */ + mapUser=function(data) { + return new User(data.username, data.password, null,data.fullName,data.email,data.permanent,data.validated, + data.timestampAccountCreation,data.timestampLastLogin,data.timestampLastPasswordChange, + data.locked,data.passwordChangeRequired,self,data.readOnly,data.userManagerId); + } + + +}); + + diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/redback/users.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/redback/users.js new file mode 100644 index 000000000..4409b0435 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/redback/users.js @@ -0,0 +1,290 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +define("redback.users",["jquery","utils","i18n","jquery.validate","knockout","knockout.simpleGrid"], +function(jquery,utils,i18n,jqueryValidate,ko,koSimpleGrid) { + + /** + * view model used for users grid + */ + UsersViewModel=function() { + this.users = ko.observableArray([]); + var self = this; + + this.gridViewModel = new ko.simpleGrid.viewModel({ + data: this.users, + viewModel: this, + columns: [ + { + headerText: "User Name", + rowText: "username"}, + { + headerText: "Full Name", + rowText: "fullName"}, + { + headerText: "Email", + rowText: "email"} + ], + pageSize: 10 + }); + + this.addUser=function() { + clearUserMessages(); + var mainContent = $("#main-content"); + mainContent.find("#createUserForm").empty(); + mainContent.find("#user-edit").remove(); + mainContent.find("#user-create").show(); + var viewModel = new UserViewModel(new User(),false,self); + $.log("UsersViewModel#addUser"); + var createUserForm = mainContent.find("#createUserForm"); + createUserForm.html(smallSpinnerImg()); + createUserForm.attr("data-bind",'template: {name:"redback/user-edit-tmpl",data: user}'); + ko.applyBindings(viewModel,createUserForm.get(0)); + mainContent.find("#createUserForm #user-create-form-cancel-button").on( "click", function(e) { + e.preventDefault(); + activateUsersGridTab(); + }); + mainContent.find("#user-create").validate({ + rules: { + confirmPassword: { + equalTo: "#password" + } + }, + showErrors: function(validator, errorMap, errorList) { + customShowError("#main-content #user-create",validator,errorMap,errorMap); + } + }); + + // desactivate roles pill when adding user + mainContent.find("#edit_user_details_pills_headers").hide(); + + }; + + lock = function(user){ + clearUserMessages(); + user.lock(); + } + + unlock = function(user){ + clearUserMessages(); + user.unlock(); + } + + passwordChangeRequire = function(user,forceChangedPassword){ + clearUserMessages(); + user.changePasswordChangeRequired(forceChangedPassword); + } + + this.sortByName = function() { + this.users.sort(function(a, b) { + return a.username < b.username ? -1 : 1; + }); + }; + + deleteUser=function(user){ + clearUserMessages(); + + var currentUser = user; + openDialogConfirm(function(){ + $.ajax("restServices/redbackServices/userService/deleteUser/"+encodeURIComponent(currentUser.username()), { + type: "GET", + dataType: 'json', + success: function(data) { + // FIXME i18n + displaySuccessMessage( $.i18n.prop("user.deleted", currentUser.username())); + self.users.remove(currentUser); + }, + complete: function() { + closeDialogConfirm(); + } + } + ); + } + ,"Ok", $.i18n.prop("cancel"), $.i18n.prop("user.delete.message", currentUser.username()), + $("#user-delete-warning-tmpl" ).tmpl(currentUser)); + + } + + editUserBox=function(user) { + $.log("editUserBox"); + clearUserMessages(); + activateUsersEditTab(); + var mainContent = $("#main-content"); + var viewModel = new UserViewModel(user,true,self); + + mainContent.find("#user-edit-roles-view" ).append(smallSpinnerImg()); + $.ajax("restServices/redbackServices/roleManagementService/getEffectivelyAssignedRoles/"+encodeURIComponent(user.username()), { + type: "GET", + dataType: 'json', + success: function(data) { + var mappedRoles = $.map(data, function(item) { + return item.name; + }); + user.assignedRoles = ko.observableArray(mappedRoles); + + // user form binding + var createUserForm = mainContent.find("#createUserForm"); + createUserForm.html(smallSpinnerImg()); + createUserForm.attr("data-bind",'template: {name:"redback/user-edit-tmpl",data: user}'); + ko.applyBindings(viewModel,createUserForm.get(0)); + + mainContent.find("#users-view-tabs-li-user-edit a").html($.i18n.prop("edit")); + + mainContent.find("#user-create" ).find("#user-create-form-cancel-button").on("click", function(e) { + e.preventDefault(); + activateUsersGridTab(); + }); + + mainContent.find("#user-create").validate({ + rules: { + confirmPassword: { + equalTo: "#password" + } + }, + showErrors: function(validator, errorMap, errorList) { + customShowError("#main-content #user-create",validator,errorMap,errorMap); + } + }); + mainContent.find("#createUserForm #user-create #user-create-form-register-button").on("click", function(e) { + e.preventDefault(); + }); + + // user roles binding + mainContent.find("#user-edit-roles-view").attr("data-bind",'template: {name:"user_view_roles_list_tmpl"}'); + ko.applyBindings(viewModel,mainContent.find("#user-edit-roles-view").get(0)); + mainContent.find("#edit_user_details_pills_headers a:first").tab('show'); + + mainContent.find("#edit_user_details_pills_headers").bind('click', function (e) { + if ($(e.target).attr("href")=="#user-edit-roles-edit") { + editUserRoles(user); + } + }) + + } + } + ); + + } + + } + + editUserRoles=function(user){ + var viewModel = new UserViewModel(user); + var mainContent = $("#main-content"); + mainContent.find("#user-edit-roles-edit").html(smallSpinnerImg()); + $.ajax("restServices/redbackServices/roleManagementService/getApplicationRoles/"+encodeURIComponent(user.username()), { + type: "GET", + dataType: 'json', + success: function(data) { + var mappedApplicationRoles = $.map(data, function(item) { + return mapApplicationRoles(item); + }); + viewModel.applicationRoles=ko.observableArray(mappedApplicationRoles); + mainContent.find("#user-edit-roles-edit").attr("data-bind",'template: {name:"user_edit_roles_tmpl"}'); + ko.applyBindings(viewModel,mainContent.find("#user-edit-roles-edit").get(0)); + $.log("assignedRoles:"+user.assignedRoles().length); + } + } + ); + } + + UserViewModel=function(user,updateMode,usersViewModel) { + this.user=user; + this.applicationRoles = ko.observableArray(new Array()); + this.usersViewModel=usersViewModel; + this.updateMode=updateMode; + var self=this; + updateUserRoles=function(){ + this.user.updateAssignedRoles(); + } + + saveUser=function(){ + var valid = $("#main-content").find("#user-create").valid(); + if (valid==false) { + return; + } + if (self.updateMode==false){ + return user.create(function(){self.usersViewModel.users.push(user)}); + } else { + return user.update(); + } + } + + } + + /** + * called from the menu to display tabs with users grid + */ + displayUsersGrid=function() { + screenChange(); + var mainContent = $("#main-content"); + mainContent.html(mediumSpinnerImg()); + mainContent.attr("data-bind",'template: {name:"usersGrid"}'); + + $.ajax("restServices/redbackServices/userService/getUsers", { + type: "GET", + dataType: 'json', + success: function(data) { + var mappedUsers = $.map(data, function(item) { + return mapUser(item); + }); + var usersViewModel = new UsersViewModel(); + usersViewModel.users(mappedUsers); + ko.applyBindings(usersViewModel,jQuery("#main-content").get(0)); + mainContent.find("#users-view-tabs a:first").tab('show'); + mainContent.find("#users-view-tabs a[data-toggle='tab']").on('show', function (e) { + //$.log( $(e.target).attr("href") ); // activated tab + //e.relatedTarget // previous tab + $.log("tabs shown"); + if ($(e.target).attr("href")=="#createUserForm") { + usersViewModel.addUser(); + } + if ($(e.target).attr("href")=="#users-view") { + mainContent.find("#users-view-tabs-li-user-edit a").html($.i18n.prop("add")); + } + + }) + mainContent.find("#users-view-tabs-content #users-view").addClass("active"); + } + } + ); + + } + + activateUsersGridTab=function(){ + var mainContent = $("#main-content"); + mainContent.find("#users-view-tabs li").removeClass("active"); + mainContent.find("#users-view-tabs-content div").removeClass("active"); + // activate users grid tab + mainContent.find("#users-view-tabs-content #users-view").addClass("active"); + mainContent.find("#users-view-tabs-li-users-grid").addClass("active"); + mainContent.find("#users-view-tabs-li-user-edit a").html($.i18n.prop("add")); + } + + activateUsersEditTab=function(){ + var mainContent = $("#main-content"); + mainContent.find("#users-view-tabs li").removeClass("active"); + mainContent.find("#users-view-tabs-content div").removeClass("active"); + // activate users edit tab + mainContent.find("#users-view-tabs-content #createUserForm").addClass("active"); + mainContent.find("#users-view-tabs-li-user-edit").addClass("active"); + } + +}); + + diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/require.2.1.2.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/require.2.1.2.js new file mode 100644 index 000000000..8de013dc9 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/require.2.1.2.js @@ -0,0 +1,35 @@ +/* + RequireJS 2.1.2 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. + Available via the MIT or new BSD license. + see: http://github.com/jrburke/requirejs for details +*/ +var requirejs,require,define; +(function(Y){function H(b){return"[object Function]"===L.call(b)}function I(b){return"[object Array]"===L.call(b)}function x(b,c){if(b){var d;for(d=0;d<b.length&&(!b[d]||!c(b[d],d,b));d+=1);}}function M(b,c){if(b){var d;for(d=b.length-1;-1<d&&(!b[d]||!c(b[d],d,b));d-=1);}}function r(b,c){return da.call(b,c)}function i(b,c){return r(b,c)&&b[c]}function E(b,c){for(var d in b)if(r(b,d)&&c(b[d],d))break}function Q(b,c,d,i){c&&E(c,function(c,h){if(d||!r(b,h))i&&"string"!==typeof c?(b[h]||(b[h]={}),Q(b[h], +c,d,i)):b[h]=c});return b}function t(b,c){return function(){return c.apply(b,arguments)}}function Z(b){if(!b)return b;var c=Y;x(b.split("."),function(b){c=c[b]});return c}function J(b,c,d,i){c=Error(c+"\nhttp://requirejs.org/docs/errors.html#"+b);c.requireType=b;c.requireModules=i;d&&(c.originalError=d);return c}function ea(b){function c(a,g,v){var e,n,b,c,d,j,f,h=g&&g.split("/");e=h;var l=m.map,k=l&&l["*"];if(a&&"."===a.charAt(0))if(g){e=i(m.pkgs,g)?h=[g]:h.slice(0,h.length-1);g=a=e.concat(a.split("/")); +for(e=0;g[e];e+=1)if(n=g[e],"."===n)g.splice(e,1),e-=1;else if(".."===n)if(1===e&&(".."===g[2]||".."===g[0]))break;else 0<e&&(g.splice(e-1,2),e-=2);e=i(m.pkgs,g=a[0]);a=a.join("/");e&&a===g+"/"+e.main&&(a=g)}else 0===a.indexOf("./")&&(a=a.substring(2));if(v&&(h||k)&&l){g=a.split("/");for(e=g.length;0<e;e-=1){b=g.slice(0,e).join("/");if(h)for(n=h.length;0<n;n-=1)if(v=i(l,h.slice(0,n).join("/")))if(v=i(v,b)){c=v;d=e;break}if(c)break;!j&&(k&&i(k,b))&&(j=i(k,b),f=e)}!c&&j&&(c=j,d=f);c&&(g.splice(0,d, +c),a=g.join("/"))}return a}function d(a){z&&x(document.getElementsByTagName("script"),function(g){if(g.getAttribute("data-requiremodule")===a&&g.getAttribute("data-requirecontext")===j.contextName)return g.parentNode.removeChild(g),!0})}function y(a){var g=i(m.paths,a);if(g&&I(g)&&1<g.length)return d(a),g.shift(),j.require.undef(a),j.require([a]),!0}function f(a){var g,b=a?a.indexOf("!"):-1;-1<b&&(g=a.substring(0,b),a=a.substring(b+1,a.length));return[g,a]}function h(a,g,b,e){var n,u,d=null,h=g?g.name: +null,l=a,m=!0,k="";a||(m=!1,a="_@r"+(L+=1));a=f(a);d=a[0];a=a[1];d&&(d=c(d,h,e),u=i(p,d));a&&(d?k=u&&u.normalize?u.normalize(a,function(a){return c(a,h,e)}):c(a,h,e):(k=c(a,h,e),a=f(k),d=a[0],k=a[1],b=!0,n=j.nameToUrl(k)));b=d&&!u&&!b?"_unnormalized"+(M+=1):"";return{prefix:d,name:k,parentMap:g,unnormalized:!!b,url:n,originalName:l,isDefine:m,id:(d?d+"!"+k:k)+b}}function q(a){var g=a.id,b=i(k,g);b||(b=k[g]=new j.Module(a));return b}function s(a,g,b){var e=a.id,n=i(k,e);if(r(p,e)&&(!n||n.defineEmitComplete))"defined"=== +g&&b(p[e]);else q(a).on(g,b)}function C(a,g){var b=a.requireModules,e=!1;if(g)g(a);else if(x(b,function(g){if(g=i(k,g))g.error=a,g.events.error&&(e=!0,g.emit("error",a))}),!e)l.onError(a)}function w(){R.length&&(fa.apply(F,[F.length-1,0].concat(R)),R=[])}function A(a,g,b){var e=a.map.id;a.error?a.emit("error",a.error):(g[e]=!0,x(a.depMaps,function(e,c){var d=e.id,h=i(k,d);h&&(!a.depMatched[c]&&!b[d])&&(i(g,d)?(a.defineDep(c,p[d]),a.check()):A(h,g,b))}),b[e]=!0)}function B(){var a,g,b,e,n=(b=1E3*m.waitSeconds)&& +j.startTime+b<(new Date).getTime(),c=[],h=[],f=!1,l=!0;if(!T){T=!0;E(k,function(b){a=b.map;g=a.id;if(b.enabled&&(a.isDefine||h.push(b),!b.error))if(!b.inited&&n)y(g)?f=e=!0:(c.push(g),d(g));else if(!b.inited&&(b.fetched&&a.isDefine)&&(f=!0,!a.prefix))return l=!1});if(n&&c.length)return b=J("timeout","Load timeout for modules: "+c,null,c),b.contextName=j.contextName,C(b);l&&x(h,function(a){A(a,{},{})});if((!n||e)&&f)if((z||$)&&!U)U=setTimeout(function(){U=0;B()},50);T=!1}}function D(a){r(p,a[0])|| +q(h(a[0],null,!0)).init(a[1],a[2])}function G(a){var a=a.currentTarget||a.srcElement,b=j.onScriptLoad;a.detachEvent&&!V?a.detachEvent("onreadystatechange",b):a.removeEventListener("load",b,!1);b=j.onScriptError;(!a.detachEvent||V)&&a.removeEventListener("error",b,!1);return{node:a,id:a&&a.getAttribute("data-requiremodule")}}function K(){var a;for(w();F.length;){a=F.shift();if(null===a[0])return C(J("mismatch","Mismatched anonymous define() module: "+a[a.length-1]));D(a)}}var T,W,j,N,U,m={waitSeconds:7, +baseUrl:"./",paths:{},pkgs:{},shim:{},map:{},config:{}},k={},X={},F=[],p={},S={},L=1,M=1;N={require:function(a){return a.require?a.require:a.require=j.makeRequire(a.map)},exports:function(a){a.usingExports=!0;if(a.map.isDefine)return a.exports?a.exports:a.exports=p[a.map.id]={}},module:function(a){return a.module?a.module:a.module={id:a.map.id,uri:a.map.url,config:function(){return m.config&&i(m.config,a.map.id)||{}},exports:p[a.map.id]}}};W=function(a){this.events=i(X,a.id)||{};this.map=a;this.shim= +i(m.shim,a.id);this.depExports=[];this.depMaps=[];this.depMatched=[];this.pluginMaps={};this.depCount=0};W.prototype={init:function(a,b,c,e){e=e||{};if(!this.inited){this.factory=b;if(c)this.on("error",c);else this.events.error&&(c=t(this,function(a){this.emit("error",a)}));this.depMaps=a&&a.slice(0);this.errback=c;this.inited=!0;this.ignore=e.ignore;e.enabled||this.enabled?this.enable():this.check()}},defineDep:function(a,b){this.depMatched[a]||(this.depMatched[a]=!0,this.depCount-=1,this.depExports[a]= +b)},fetch:function(){if(!this.fetched){this.fetched=!0;j.startTime=(new Date).getTime();var a=this.map;if(this.shim)j.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],t(this,function(){return a.prefix?this.callPlugin():this.load()}));else return a.prefix?this.callPlugin():this.load()}},load:function(){var a=this.map.url;S[a]||(S[a]=!0,j.load(this.map.id,a))},check:function(){if(this.enabled&&!this.enabling){var a,b,c=this.map.id;b=this.depExports;var e=this.exports,n=this.factory; +if(this.inited)if(this.error)this.emit("error",this.error);else{if(!this.defining){this.defining=!0;if(1>this.depCount&&!this.defined){if(H(n)){if(this.events.error)try{e=j.execCb(c,n,b,e)}catch(d){a=d}else e=j.execCb(c,n,b,e);this.map.isDefine&&((b=this.module)&&void 0!==b.exports&&b.exports!==this.exports?e=b.exports:void 0===e&&this.usingExports&&(e=this.exports));if(a)return a.requireMap=this.map,a.requireModules=[this.map.id],a.requireType="define",C(this.error=a)}else e=n;this.exports=e;if(this.map.isDefine&& +!this.ignore&&(p[c]=e,l.onResourceLoad))l.onResourceLoad(j,this.map,this.depMaps);delete k[c];this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a=this.map,b=a.id,d=h(a.prefix);this.depMaps.push(d);s(d,"defined",t(this,function(e){var n,d;d=this.map.name;var v=this.map.parentMap?this.map.parentMap.name:null,f=j.makeRequire(a.parentMap,{enableBuildCallback:!0, +skipMap:!0});if(this.map.unnormalized){if(e.normalize&&(d=e.normalize(d,function(a){return c(a,v,!0)})||""),e=h(a.prefix+"!"+d,this.map.parentMap),s(e,"defined",t(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),d=i(k,e.id)){this.depMaps.push(e);if(this.events.error)d.on("error",t(this,function(a){this.emit("error",a)}));d.enable()}}else n=t(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),n.error=t(this,function(a){this.inited=!0;this.error= +a;a.requireModules=[b];E(k,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&delete k[a.map.id]});C(a)}),n.fromText=t(this,function(e,c){var d=a.name,u=h(d),v=O;c&&(e=c);v&&(O=!1);q(u);r(m.config,b)&&(m.config[d]=m.config[b]);try{l.exec(e)}catch(k){throw Error("fromText eval for "+d+" failed: "+k);}v&&(O=!0);this.depMaps.push(u);j.completeLoad(d);f([d],n)}),e.load(a.name,f,n,m)}));j.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){this.enabling=this.enabled=!0;x(this.depMaps,t(this,function(a, +b){var c,e;if("string"===typeof a){a=h(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=i(N,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;s(a,"defined",t(this,function(a){this.defineDep(b,a);this.check()}));this.errback&&s(a,"error",this.errback)}c=a.id;e=k[c];!r(N,c)&&(e&&!e.enabled)&&j.enable(a,this)}));E(this.pluginMaps,t(this,function(a){var b=i(k,a.id);b&&!b.enabled&&j.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c= +this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){x(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};j={config:m,contextName:b,registry:k,defined:p,urlFetched:S,defQueue:F,Module:W,makeModuleMap:h,nextTick:l.nextTick,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=m.pkgs,c=m.shim,e={paths:!0,config:!0,map:!0};E(a,function(a,b){e[b]?"map"===b?Q(m[b],a,!0,!0):Q(m[b],a,!0):m[b]=a});a.shim&&(E(a.shim,function(a, +b){I(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=j.makeShimExports(a);c[b]=a}),m.shim=c);a.packages&&(x(a.packages,function(a){a="string"===typeof a?{name:a}:a;b[a.name]={name:a.name,location:a.location||a.name,main:(a.main||"main").replace(ga,"").replace(aa,"")}}),m.pkgs=b);E(k,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=h(b))});if(a.deps||a.callback)j.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(Y,arguments)); +return b||a.exports&&Z(a.exports)}},makeRequire:function(a,d){function f(e,c,u){var i,m;d.enableBuildCallback&&(c&&H(c))&&(c.__requireJsBuild=!0);if("string"===typeof e){if(H(c))return C(J("requireargs","Invalid require call"),u);if(a&&r(N,e))return N[e](k[a.id]);if(l.get)return l.get(j,e,a);i=h(e,a,!1,!0);i=i.id;return!r(p,i)?C(J("notloaded",'Module name "'+i+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):p[i]}K();j.nextTick(function(){K();m=q(h(null,a));m.skipMap=d.skipMap; +m.init(e,c,u,{enabled:!0});B()});return f}d=d||{};Q(f,{isBrowser:z,toUrl:function(b){var d=b.lastIndexOf("."),g=null;-1!==d&&(g=b.substring(d,b.length),b=b.substring(0,d));return j.nameToUrl(c(b,a&&a.id,!0),g)},defined:function(b){return r(p,h(b,a,!1,!0).id)},specified:function(b){b=h(b,a,!1,!0).id;return r(p,b)||r(k,b)}});a||(f.undef=function(b){w();var c=h(b,a,!0),d=i(k,b);delete p[b];delete S[c.url];delete X[b];d&&(d.events.defined&&(X[b]=d.events),delete k[b])});return f},enable:function(a){i(k, +a.id)&&q(a).enable()},completeLoad:function(a){var b,c,d=i(m.shim,a)||{},h=d.exports;for(w();F.length;){c=F.shift();if(null===c[0]){c[0]=a;if(b)break;b=!0}else c[0]===a&&(b=!0);D(c)}c=i(k,a);if(!b&&!r(p,a)&&c&&!c.inited){if(m.enforceDefine&&(!h||!Z(h)))return y(a)?void 0:C(J("nodefine","No define call for "+a,null,[a]));D([a,d.deps||[],d.exportsFn])}B()},nameToUrl:function(a,b){var c,d,h,f,j,k;if(l.jsExtRegExp.test(a))f=a+(b||"");else{c=m.paths;d=m.pkgs;f=a.split("/");for(j=f.length;0<j;j-=1)if(k= +f.slice(0,j).join("/"),h=i(d,k),k=i(c,k)){I(k)&&(k=k[0]);f.splice(0,j,k);break}else if(h){c=a===h.name?h.location+"/"+h.main:h.location;f.splice(0,j,c);break}f=f.join("/");f+=b||(/\?/.test(f)?"":".js");f=("/"===f.charAt(0)||f.match(/^[\w\+\.\-]+:/)?"":m.baseUrl)+f}return m.urlArgs?f+((-1===f.indexOf("?")?"?":"&")+m.urlArgs):f},load:function(a,b){l.load(j,a,b)},execCb:function(a,b,c,d){return b.apply(d,c)},onScriptLoad:function(a){if("load"===a.type||ha.test((a.currentTarget||a.srcElement).readyState))P= +null,a=G(a),j.completeLoad(a.id)},onScriptError:function(a){var b=G(a);if(!y(b.id))return C(J("scripterror","Script error",a,[b.id]))}};j.require=j.makeRequire();return j}var l,w,A,D,s,G,P,K,ba,ca,ia=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,ja=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,aa=/\.js$/,ga=/^\.\//;w=Object.prototype;var L=w.toString,da=w.hasOwnProperty,fa=Array.prototype.splice,z=!!("undefined"!==typeof window&&navigator&&document),$=!z&&"undefined"!==typeof importScripts,ha=z&& +"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,V="undefined"!==typeof opera&&"[object Opera]"===opera.toString(),B={},q={},R=[],O=!1;if("undefined"===typeof define){if("undefined"!==typeof requirejs){if(H(requirejs))return;q=requirejs;requirejs=void 0}"undefined"!==typeof require&&!H(require)&&(q=require,require=void 0);l=requirejs=function(b,c,d,y){var f,h="_";!I(b)&&"string"!==typeof b&&(f=b,I(c)?(b=c,c=d,d=y):b=[]);f&&f.context&&(h=f.context);(y=i(B,h))||(y=B[h]=l.s.newContext(h)); +f&&y.configure(f);return y.require(b,c,d)};l.config=function(b){return l(b)};l.nextTick="undefined"!==typeof setTimeout?function(b){setTimeout(b,4)}:function(b){b()};require||(require=l);l.version="2.1.2";l.jsExtRegExp=/^\/|:|\?|\.js$/;l.isBrowser=z;w=l.s={contexts:B,newContext:ea};l({});x(["toUrl","undef","defined","specified"],function(b){l[b]=function(){var c=B._;return c.require[b].apply(c,arguments)}});if(z&&(A=w.head=document.getElementsByTagName("head")[0],D=document.getElementsByTagName("base")[0]))A= +w.head=D.parentNode;l.onError=function(b){throw b;};l.load=function(b,c,d){var i=b&&b.config||{},f;if(z)return f=i.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script"),f.type=i.scriptType||"text/javascript",f.charset="utf-8",f.async=!0,f.setAttribute("data-requirecontext",b.contextName),f.setAttribute("data-requiremodule",c),f.attachEvent&&!(f.attachEvent.toString&&0>f.attachEvent.toString().indexOf("[native code"))&&!V?(O=!0,f.attachEvent("onreadystatechange", +b.onScriptLoad)):(f.addEventListener("load",b.onScriptLoad,!1),f.addEventListener("error",b.onScriptError,!1)),f.src=d,K=f,D?A.insertBefore(f,D):A.appendChild(f),K=null,f;$&&(importScripts(d),b.completeLoad(c))};z&&M(document.getElementsByTagName("script"),function(b){A||(A=b.parentNode);if(s=b.getAttribute("data-main"))return q.baseUrl||(G=s.split("/"),ba=G.pop(),ca=G.length?G.join("/")+"/":"./",q.baseUrl=ca,s=ba),s=s.replace(aa,""),q.deps=q.deps?q.deps.concat(s):[s],!0});define=function(b,c,d){var i, +f;"string"!==typeof b&&(d=c,c=b,b=null);I(c)||(d=c,c=[]);!c.length&&H(d)&&d.length&&(d.toString().replace(ia,"").replace(ja,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c));if(O){if(!(i=K))P&&"interactive"===P.readyState||M(document.getElementsByTagName("script"),function(b){if("interactive"===b.readyState)return P=b}),i=P;i&&(b||(b=i.getAttribute("data-requiremodule")),f=B[i.getAttribute("data-requirecontext")])}(f?f.defQueue:R).push([b,c,d])};define.amd= +{jQuery:!0};l.exec=function(b){return eval(b)};l(q)}})(this); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/sammy.0.7.1.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/sammy.0.7.1.js new file mode 100644 index 000000000..c756e225e --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/sammy.0.7.1.js @@ -0,0 +1,2003 @@ +// name: sammy +// version: 0.7.1 + +// Sammy.js / http://sammyjs.org + +(function($, window) { + (function(factory){ + // Support module loading scenarios + if (typeof define === 'function' && define.amd){ + // AMD Anonymous Module + define(['jquery'], factory); + } else { + // No module loader (plain <script> tag) - put directly in global namespace + $.sammy = window.Sammy = factory($); + } + })(function($){ + var Sammy, + PATH_REPLACER = "([^\/]+)", + PATH_NAME_MATCHER = /:([\w\d]+)/g, + QUERY_STRING_MATCHER = /\?([^#]*)?$/, + // mainly for making `arguments` an Array + _makeArray = function(nonarray) { return Array.prototype.slice.call(nonarray); }, + // borrowed from jQuery + _isFunction = function( obj ) { return Object.prototype.toString.call(obj) === "[object Function]"; }, + _isArray = function( obj ) { return Object.prototype.toString.call(obj) === "[object Array]"; }, + _isRegExp = function( obj ) { return Object.prototype.toString.call(obj) === "[object RegExp]"; }, + _decode = function( str ) { return decodeURIComponent((str || '').replace(/\+/g, ' ')); }, + _encode = encodeURIComponent, + _escapeHTML = function(s) { + return String(s).replace(/&(?!\w+;)/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"'); + }, + _routeWrapper = function(verb) { + return function(path, callback) { return this.route.apply(this, [verb, path, callback]); }; + }, + _template_cache = {}, + _has_history = !!(window.history && history.pushState), + loggers = []; + + + // `Sammy` (also aliased as $.sammy) is not only the namespace for a + // number of prototypes, its also a top level method that allows for easy + // creation/management of `Sammy.Application` instances. There are a + // number of different forms for `Sammy()` but each returns an instance + // of `Sammy.Application`. When a new instance is created using + // `Sammy` it is added to an Object called `Sammy.apps`. This + // provides for an easy way to get at existing Sammy applications. Only one + // instance is allowed per `element_selector` so when calling + // `Sammy('selector')` multiple times, the first time will create + // the application and the following times will extend the application + // already added to that selector. + // + // ### Example + // + // // returns the app at #main or a new app + // Sammy('#main') + // + // // equivalent to "new Sammy.Application", except appends to apps + // Sammy(); + // Sammy(function() { ... }); + // + // // extends the app at '#main' with function. + // Sammy('#main', function() { ... }); + // + Sammy = function() { + var args = _makeArray(arguments), + app, selector; + Sammy.apps = Sammy.apps || {}; + if (args.length === 0 || args[0] && _isFunction(args[0])) { // Sammy() + return Sammy.apply(Sammy, ['body'].concat(args)); + } else if (typeof (selector = args.shift()) == 'string') { // Sammy('#main') + app = Sammy.apps[selector] || new Sammy.Application(); + app.element_selector = selector; + if (args.length > 0) { + $.each(args, function(i, plugin) { + app.use(plugin); + }); + } + // if the selector changes make sure the reference in Sammy.apps changes + if (app.element_selector != selector) { + delete Sammy.apps[selector]; + } + Sammy.apps[app.element_selector] = app; + return app; + } + }; + + Sammy.VERSION = '0.7.1'; + + // Add to the global logger pool. Takes a function that accepts an + // unknown number of arguments and should print them or send them somewhere + // The first argument is always a timestamp. + Sammy.addLogger = function(logger) { + loggers.push(logger); + }; + + // Sends a log message to each logger listed in the global + // loggers pool. Can take any number of arguments. + // Also prefixes the arguments with a timestamp. + Sammy.log = function() { + var args = _makeArray(arguments); + args.unshift("[" + Date() + "]"); + $.each(loggers, function(i, logger) { + logger.apply(Sammy, args); + }); + }; + + if (typeof window.console != 'undefined') { + if (_isFunction(window.console.log.apply)) { + Sammy.addLogger(function() { + window.console.log.apply(window.console, arguments); + }); + } else { + Sammy.addLogger(function() { + window.console.log(arguments); + }); + } + } else if (typeof console != 'undefined') { + Sammy.addLogger(function() { + console.log.apply(console, arguments); + }); + } + + $.extend(Sammy, { + makeArray: _makeArray, + isFunction: _isFunction, + isArray: _isArray + }); + + // Sammy.Object is the base for all other Sammy classes. It provides some useful + // functionality, including cloning, iterating, etc. + Sammy.Object = function(obj) { // constructor + return $.extend(this, obj || {}); + }; + + $.extend(Sammy.Object.prototype, { + + // Escape HTML in string, use in templates to prevent script injection. + // Also aliased as `h()` + escapeHTML: _escapeHTML, + h: _escapeHTML, + + // Returns a copy of the object with Functions removed. + toHash: function() { + var json = {}; + $.each(this, function(k,v) { + if (!_isFunction(v)) { + json[k] = v; + } + }); + return json; + }, + + // Renders a simple HTML version of this Objects attributes. + // Does not render functions. + // For example. Given this Sammy.Object: + // + // var s = new Sammy.Object({first_name: 'Sammy', last_name: 'Davis Jr.'}); + // s.toHTML() + // //=> '<strong>first_name</strong> Sammy<br /><strong>last_name</strong> Davis Jr.<br />' + // + toHTML: function() { + var display = ""; + $.each(this, function(k, v) { + if (!_isFunction(v)) { + display += "<strong>" + k + "</strong> " + v + "<br />"; + } + }); + return display; + }, + + // Returns an array of keys for this object. If `attributes_only` + // is true will not return keys that map to a `function()` + keys: function(attributes_only) { + var keys = []; + for (var property in this) { + if (!_isFunction(this[property]) || !attributes_only) { + keys.push(property); + } + } + return keys; + }, + + // Checks if the object has a value at `key` and that the value is not empty + has: function(key) { + return this[key] && $.trim(this[key].toString()) !== ''; + }, + + // convenience method to join as many arguments as you want + // by the first argument - useful for making paths + join: function() { + var args = _makeArray(arguments); + var delimiter = args.shift(); + return args.join(delimiter); + }, + + // Shortcut to Sammy.log + log: function() { + Sammy.log.apply(Sammy, arguments); + }, + + // Returns a string representation of this object. + // if `include_functions` is true, it will also toString() the + // methods of this object. By default only prints the attributes. + toString: function(include_functions) { + var s = []; + $.each(this, function(k, v) { + if (!_isFunction(v) || include_functions) { + s.push('"' + k + '": ' + v.toString()); + } + }); + return "Sammy.Object: {" + s.join(',') + "}"; + } + }); + + // The DefaultLocationProxy is the default location proxy for all Sammy applications. + // A location proxy is a prototype that conforms to a simple interface. The purpose + // of a location proxy is to notify the Sammy.Application its bound to when the location + // or 'external state' changes. + // + // The `DefaultLocationProxy` watches for changes to the path of the current window and + // is also able to set the path based on changes in the application. It does this by + // using different methods depending on what is available in the current browser. In + // the latest and greatest browsers it used the HTML5 History API and the `pushState` + // `popState` events/methods. This allows you to use Sammy to serve a site behind normal + // URI paths as opposed to the older default of hash (#) based routing. Because the server + // can interpret the changed path on a refresh or re-entry, though, it requires additional + // support on the server side. If you'd like to force disable HTML5 history support, please + // use the `disable_push_state` setting on `Sammy.Application`. If pushState support + // is enabled, `DefaultLocationProxy` also binds to all links on the page. If a link is clicked + // that matches the current set of routes, the URL is changed using pushState instead of + // fully setting the location and the app is notified of the change. + // + // If the browser does not have support for HTML5 History, `DefaultLocationProxy` automatically + // falls back to the older hash based routing. The newest browsers (IE, Safari > 4, FF >= 3.6) + // support a 'onhashchange' DOM event, thats fired whenever the location.hash changes. + // In this situation the DefaultLocationProxy just binds to this event and delegates it to + // the application. In the case of older browsers a poller is set up to track changes to the + // hash. + Sammy.DefaultLocationProxy = function(app, run_interval_every) { + this.app = app; + // set is native to false and start the poller immediately + this.is_native = false; + this.has_history = _has_history; + this._startPolling(run_interval_every); + }; + + Sammy.DefaultLocationProxy.fullPath = function(location_obj) { + // Bypass the `window.location.hash` attribute. If a question mark + // appears in the hash IE6 will strip it and all of the following + // characters from `window.location.hash`. + var matches = location_obj.toString().match(/^[^#]*(#.+)$/); + var hash = matches ? matches[1] : ''; + return [location_obj.pathname, location_obj.search, hash].join(''); + }; +$.extend(Sammy.DefaultLocationProxy.prototype , { + // bind the proxy events to the current app. + bind: function() { + var proxy = this, app = this.app, lp = Sammy.DefaultLocationProxy; + $(window).bind('hashchange.' + this.app.eventNamespace(), function(e, non_native) { + // if we receive a native hash change event, set the proxy accordingly + // and stop polling + if (proxy.is_native === false && !non_native) { + proxy.is_native = true; + window.clearInterval(lp._interval); + } + app.trigger('location-changed'); + }); + if (_has_history && !app.disable_push_state) { + // bind to popstate + $(window).bind('popstate.' + this.app.eventNamespace(), function(e) { + app.trigger('location-changed'); + }); + // bind to link clicks that have routes + $('a').live('click.history-' + this.app.eventNamespace(), function(e) { + if (e.isDefaultPrevented() || e.metaKey || e.ctrlKey) { + return; + } + var full_path = lp.fullPath(this); + if (this.hostname == window.location.hostname && + app.lookupRoute('get', full_path) && + this.target !== '_blank') { + e.preventDefault(); + proxy.setLocation(full_path); + return false; + } + }); + } + if (!lp._bindings) { + lp._bindings = 0; + } + lp._bindings++; + }, + + // unbind the proxy events from the current app + unbind: function() { + $(window).unbind('hashchange.' + this.app.eventNamespace()); + $(window).unbind('popstate.' + this.app.eventNamespace()); + $('a').die('click.history-' + this.app.eventNamespace()); + Sammy.DefaultLocationProxy._bindings--; + if (Sammy.DefaultLocationProxy._bindings <= 0) { + window.clearInterval(Sammy.DefaultLocationProxy._interval); + } + }, + + // get the current location from the hash. + getLocation: function() { + return Sammy.DefaultLocationProxy.fullPath(window.location); + }, + + // set the current location to `new_location` + setLocation: function(new_location) { + if (/^([^#\/]|$)/.test(new_location)) { // non-prefixed url + if (_has_history && !this.app.disable_push_state) { + new_location = '/' + new_location; + } else { + new_location = '#!/' + new_location; + } + } + if (new_location != this.getLocation()) { + // HTML5 History exists and new_location is a full path + if (_has_history && !this.app.disable_push_state && /^\//.test(new_location)) { + history.pushState({ path: new_location }, window.title, new_location); + this.app.trigger('location-changed'); + } else { + return (window.location = new_location); + } + } + }, + + _startPolling: function(every) { + // set up interval + var proxy = this; + if (!Sammy.DefaultLocationProxy._interval) { + if (!every) { every = 10; } + var hashCheck = function() { + var current_location = proxy.getLocation(); + if (typeof Sammy.DefaultLocationProxy._last_location == 'undefined' || + current_location != Sammy.DefaultLocationProxy._last_location) { + window.setTimeout(function() { + $(window).trigger('hashchange', [true]); + }, 0); + } + Sammy.DefaultLocationProxy._last_location = current_location; + }; + hashCheck(); + Sammy.DefaultLocationProxy._interval = window.setInterval(hashCheck, every); + } + } + }); + + + // Sammy.Application is the Base prototype for defining 'applications'. + // An 'application' is a collection of 'routes' and bound events that is + // attached to an element when `run()` is called. + // The only argument an 'app_function' is evaluated within the context of the application. + Sammy.Application = function(app_function) { + var app = this; + this.routes = {}; + this.listeners = new Sammy.Object({}); + this.arounds = []; + this.befores = []; + // generate a unique namespace + this.namespace = (new Date()).getTime() + '-' + parseInt(Math.random() * 1000, 10); + this.context_prototype = function() { Sammy.EventContext.apply(this, arguments); }; + this.context_prototype.prototype = new Sammy.EventContext(); + + if (_isFunction(app_function)) { + app_function.apply(this, [this]); + } + // set the location proxy if not defined to the default (DefaultLocationProxy) + if (!this._location_proxy) { + this.setLocationProxy(new Sammy.DefaultLocationProxy(this, this.run_interval_every)); + } + if (this.debug) { + this.bindToAllEvents(function(e, data) { + app.log(app.toString(), e.cleaned_type, data || {}); + }); + } + }; + + Sammy.Application.prototype = $.extend({}, Sammy.Object.prototype, { + + // the four route verbs + ROUTE_VERBS: ['get','post','put','delete'], + + // An array of the default events triggered by the + // application during its lifecycle + APP_EVENTS: ['run', 'unload', 'lookup-route', 'run-route', 'route-found', 'event-context-before', 'event-context-after', 'changed', 'error', 'check-form-submission', 'redirect', 'location-changed'], + + _last_route: null, + _location_proxy: null, + _running: false, + + // Defines what element the application is bound to. Provide a selector + // (parseable by `jQuery()`) and this will be used by `$element()` + element_selector: 'body', + + // When set to true, logs all of the default events using `log()` + debug: false, + + // When set to true, and the error() handler is not overridden, will actually + // raise JS errors in routes (500) and when routes can't be found (404) + raise_errors: false, + + // The time in milliseconds that the URL is queried for changes + run_interval_every: 50, + + // if using the `DefaultLocationProxy` setting this to true will force the app to use + // traditional hash based routing as opposed to the new HTML5 PushState support + disable_push_state: false, + + // The default template engine to use when using `partial()` in an + // `EventContext`. `template_engine` can either be a string that + // corresponds to the name of a method/helper on EventContext or it can be a function + // that takes two arguments, the content of the unrendered partial and an optional + // JS object that contains interpolation data. Template engine is only called/referred + // to if the extension of the partial is null or unknown. See `partial()` + // for more information + template_engine: null, + + // //=> Sammy.Application: body + toString: function() { + return 'Sammy.Application:' + this.element_selector; + }, + + // returns a jQuery object of the Applications bound element. + $element: function(selector) { + return selector ? $(this.element_selector).find(selector) : $(this.element_selector); + }, + + // `use()` is the entry point for including Sammy plugins. + // The first argument to use should be a function() that is evaluated + // in the context of the current application, just like the `app_function` + // argument to the `Sammy.Application` constructor. + // + // Any additional arguments are passed to the app function sequentially. + // + // For much more detail about plugins, check out: + // [http://sammyjs.org/docs/plugins](http://sammyjs.org/docs/plugins) + // + // ### Example + // + // var MyPlugin = function(app, prepend) { + // + // this.helpers({ + // myhelper: function(text) { + // alert(prepend + " " + text); + // } + // }); + // + // }; + // + // var app = $.sammy(function() { + // + // this.use(MyPlugin, 'This is my plugin'); + // + // this.get('#/', function() { + // this.myhelper('and dont you forget it!'); + // //=> Alerts: This is my plugin and dont you forget it! + // }); + // + // }); + // + // If plugin is passed as a string it assumes your are trying to load + // Sammy."Plugin". This is the preferred way of loading core Sammy plugins + // as it allows for better error-messaging. + // + // ### Example + // + // $.sammy(function() { + // this.use('Mustache'); //=> Sammy.Mustache + // this.use('Storage'); //=> Sammy.Storage + // }); + // + use: function() { + // flatten the arguments + var args = _makeArray(arguments), + plugin = args.shift(), + plugin_name = plugin || ''; + try { + args.unshift(this); + if (typeof plugin == 'string') { + plugin_name = 'Sammy.' + plugin; + plugin = Sammy[plugin]; + } + plugin.apply(this, args); + } catch(e) { + if (typeof plugin === 'undefined') { + this.error("Plugin Error: called use() but plugin (" + plugin_name.toString() + ") is not defined", e); + } else if (!_isFunction(plugin)) { + this.error("Plugin Error: called use() but '" + plugin_name.toString() + "' is not a function", e); + } else { + this.error("Plugin Error", e); + } + } + return this; + }, + + // Sets the location proxy for the current app. By default this is set to + // a new `Sammy.DefaultLocationProxy` on initialization. However, you can set + // the location_proxy inside you're app function to give your app a custom + // location mechanism. See `Sammy.DefaultLocationProxy` and `Sammy.DataLocationProxy` + // for examples. + // + // `setLocationProxy()` takes an initialized location proxy. + // + // ### Example + // + // // to bind to data instead of the default hash; + // var app = $.sammy(function() { + // this.setLocationProxy(new Sammy.DataLocationProxy(this)); + // }); + // + setLocationProxy: function(new_proxy) { + var original_proxy = this._location_proxy; + this._location_proxy = new_proxy; + if (this.isRunning()) { + if (original_proxy) { + // if there is already a location proxy, unbind it. + original_proxy.unbind(); + } + this._location_proxy.bind(); + } + }, + + // provide log() override for inside an app that includes the relevant application element_selector + log: function() { + Sammy.log.apply(Sammy, Array.prototype.concat.apply([this.element_selector],arguments)); + }, + + + // `route()` is the main method for defining routes within an application. + // For great detail on routes, check out: + // [http://sammyjs.org/docs/routes](http://sammyjs.org/docs/routes) + // + // This method also has aliases for each of the different verbs (eg. `get()`, `post()`, etc.) + // + // ### Arguments + // + // * `verb` A String in the set of ROUTE_VERBS or 'any'. 'any' will add routes for each + // of the ROUTE_VERBS. If only two arguments are passed, + // the first argument is the path, the second is the callback and the verb + // is assumed to be 'any'. + // * `path` A Regexp or a String representing the path to match to invoke this verb. + // * `callback` A Function that is called/evaluated when the route is run see: `runRoute()`. + // It is also possible to pass a string as the callback, which is looked up as the name + // of a method on the application. + // + route: function(verb, path, callback) { + var app = this, param_names = [], add_route, path_match; + + // if the method signature is just (path, callback) + // assume the verb is 'any' + if (!callback && _isFunction(path)) { + path = verb; + callback = path; + verb = 'any'; + } + + verb = verb.toLowerCase(); // ensure verb is lower case + + // if path is a string turn it into a regex + if (path.constructor == String) { + + // Needs to be explicitly set because IE will maintain the index unless NULL is returned, + // which means that with two consecutive routes that contain params, the second set of params will not be found and end up in splat instead of params + // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/RegExp/lastIndex + PATH_NAME_MATCHER.lastIndex = 0; + + // find the names + while ((path_match = PATH_NAME_MATCHER.exec(path)) !== null) { + param_names.push(path_match[1]); + } + // replace with the path replacement + path = new RegExp(path.replace(PATH_NAME_MATCHER, PATH_REPLACER) + "$"); + } + // lookup callback + if (typeof callback == 'string') { + callback = app[callback]; + } + + add_route = function(with_verb) { + var r = {verb: with_verb, path: path, callback: callback, param_names: param_names}; + // add route to routes array + app.routes[with_verb] = app.routes[with_verb] || []; + // place routes in order of definition + app.routes[with_verb].push(r); + }; + + if (verb === 'any') { + $.each(this.ROUTE_VERBS, function(i, v) { add_route(v); }); + } else { + add_route(verb); + } + + // return the app + return this; + }, + + // Alias for route('get', ...) + get: _routeWrapper('get'), + + // Alias for route('post', ...) + post: _routeWrapper('post'), + + // Alias for route('put', ...) + put: _routeWrapper('put'), + + // Alias for route('delete', ...) + del: _routeWrapper('delete'), + + // Alias for route('any', ...) + any: _routeWrapper('any'), + + // `mapRoutes` takes an array of arrays, each array being passed to route() + // as arguments, this allows for mass definition of routes. Another benefit is + // this makes it possible/easier to load routes via remote JSON. + // + // ### Example + // + // var app = $.sammy(function() { + // + // this.mapRoutes([ + // ['get', '#/', function() { this.log('index'); }], + // // strings in callbacks are looked up as methods on the app + // ['post', '#/create', 'addUser'], + // // No verb assumes 'any' as the verb + // [/dowhatever/, function() { this.log(this.verb, this.path)}]; + // ]); + // }); + // + mapRoutes: function(route_array) { + var app = this; + $.each(route_array, function(i, route_args) { + app.route.apply(app, route_args); + }); + return this; + }, + + // A unique event namespace defined per application. + // All events bound with `bind()` are automatically bound within this space. + eventNamespace: function() { + return ['sammy-app', this.namespace].join('-'); + }, + + // Works just like `jQuery.fn.bind()` with a couple notable differences. + // + // * It binds all events to the application element + // * All events are bound within the `eventNamespace()` + // * Events are not actually bound until the application is started with `run()` + // * callbacks are evaluated within the context of a Sammy.EventContext + // + bind: function(name, data, callback) { + var app = this; + // build the callback + // if the arity is 2, callback is the second argument + if (typeof callback == 'undefined') { callback = data; } + var listener_callback = function() { + // pull off the context from the arguments to the callback + var e, context, data; + e = arguments[0]; + data = arguments[1]; + if (data && data.context) { + context = data.context; + delete data.context; + } else { + context = new app.context_prototype(app, 'bind', e.type, data, e.target); + } + e.cleaned_type = e.type.replace(app.eventNamespace(), ''); + callback.apply(context, [e, data]); + }; + + // it could be that the app element doesnt exist yet + // so attach to the listeners array and then run() + // will actually bind the event. + if (!this.listeners[name]) { this.listeners[name] = []; } + this.listeners[name].push(listener_callback); + if (this.isRunning()) { + // if the app is running + // *actually* bind the event to the app element + this._listen(name, listener_callback); + } + return this; + }, + + // Triggers custom events defined with `bind()` + // + // ### Arguments + // + // * `name` The name of the event. Automatically prefixed with the `eventNamespace()` + // * `data` An optional Object that can be passed to the bound callback. + // * `context` An optional context/Object in which to execute the bound callback. + // If no context is supplied a the context is a new `Sammy.EventContext` + // + trigger: function(name, data) { + this.$element().trigger([name, this.eventNamespace()].join('.'), [data]); + return this; + }, + + // Reruns the current route + refresh: function() { + this.last_location = null; + this.trigger('location-changed'); + return this; + }, + + // Takes a single callback that is pushed on to a stack. + // Before any route is run, the callbacks are evaluated in order within + // the current `Sammy.EventContext` + // + // If any of the callbacks explicitly return false, execution of any + // further callbacks and the route itself is halted. + // + // You can also provide a set of options that will define when to run this + // before based on the route it proceeds. + // + // ### Example + // + // var app = $.sammy(function() { + // + // // will run at #/route but not at #/ + // this.before('#/route', function() { + // //... + // }); + // + // // will run at #/ but not at #/route + // this.before({except: {path: '#/route'}}, function() { + // this.log('not before #/route'); + // }); + // + // this.get('#/', function() {}); + // + // this.get('#/route', function() {}); + // + // }); + // + // See `contextMatchesOptions()` for a full list of supported options + // + before: function(options, callback) { + if (_isFunction(options)) { + callback = options; + options = {}; + } + this.befores.push([options, callback]); + return this; + }, + + // A shortcut for binding a callback to be run after a route is executed. + // After callbacks have no guarunteed order. + after: function(callback) { + return this.bind('event-context-after', callback); + }, + + + // Adds an around filter to the application. around filters are functions + // that take a single argument `callback` which is the entire route + // execution path wrapped up in a closure. This means you can decide whether + // or not to proceed with execution by not invoking `callback` or, + // more usefully wrapping callback inside the result of an asynchronous execution. + // + // ### Example + // + // The most common use case for around() is calling a _possibly_ async function + // and executing the route within the functions callback: + // + // var app = $.sammy(function() { + // + // var current_user = false; + // + // function checkLoggedIn(callback) { + // // /session returns a JSON representation of the logged in user + // // or an empty object + // if (!current_user) { + // $.getJSON('/session', function(json) { + // if (json.login) { + // // show the user as logged in + // current_user = json; + // // execute the route path + // callback(); + // } else { + // // show the user as not logged in + // current_user = false; + // // the context of aroundFilters is an EventContext + // this.redirect('#/login'); + // } + // }); + // } else { + // // execute the route path + // callback(); + // } + // }; + // + // this.around(checkLoggedIn); + // + // }); + // + around: function(callback) { + this.arounds.push(callback); + return this; + }, + + // Returns `true` if the current application is running. + isRunning: function() { + return this._running; + }, + + // Helpers extends the EventContext prototype specific to this app. + // This allows you to define app specific helper functions that can be used + // whenever you're inside of an event context (templates, routes, bind). + // + // ### Example + // + // var app = $.sammy(function() { + // + // helpers({ + // upcase: function(text) { + // return text.toString().toUpperCase(); + // } + // }); + // + // get('#/', function() { with(this) { + // // inside of this context I can use the helpers + // $('#main').html(upcase($('#main').text()); + // }}); + // + // }); + // + // + // ### Arguments + // + // * `extensions` An object collection of functions to extend the context. + // + helpers: function(extensions) { + $.extend(this.context_prototype.prototype, extensions); + return this; + }, + + // Helper extends the event context just like `helpers()` but does it + // a single method at a time. This is especially useful for dynamically named + // helpers + // + // ### Example + // + // // Trivial example that adds 3 helper methods to the context dynamically + // var app = $.sammy(function(app) { + // + // $.each([1,2,3], function(i, num) { + // app.helper('helper' + num, function() { + // this.log("I'm helper number " + num); + // }); + // }); + // + // this.get('#/', function() { + // this.helper2(); //=> I'm helper number 2 + // }); + // }); + // + // ### Arguments + // + // * `name` The name of the method + // * `method` The function to be added to the prototype at `name` + // + helper: function(name, method) { + this.context_prototype.prototype[name] = method; + return this; + }, + + // Actually starts the application's lifecycle. `run()` should be invoked + // within a document.ready block to ensure the DOM exists before binding events, etc. + // + // ### Example + // + // var app = $.sammy(function() { ... }); // your application + // $(function() { // document.ready + // app.run(); + // }); + // + // ### Arguments + // + // * `start_url` Optionally, a String can be passed which the App will redirect to + // after the events/routes have been bound. + run: function(start_url) { + if (this.isRunning()) { return false; } + var app = this; + + // actually bind all the listeners + $.each(this.listeners.toHash(), function(name, callbacks) { + $.each(callbacks, function(i, listener_callback) { + app._listen(name, listener_callback); + }); + }); + + this.trigger('run', {start_url: start_url}); + this._running = true; + // set last location + this.last_location = null; + if (!(/\#(.+)/.test(this.getLocation())) && typeof start_url != 'undefined') { + this.setLocation(start_url); + } + // check url + this._checkLocation(); + this._location_proxy.bind(); + this.bind('location-changed', function() { + app._checkLocation(); + }); + + // bind to submit to capture post/put/delete routes + this.bind('submit', function(e) { + var returned = app._checkFormSubmission($(e.target).closest('form')); + return (returned === false) ? e.preventDefault() : false; + }); + + // bind unload to body unload + $(window).bind('unload', function() { + app.unload(); + }); + + // trigger html changed + return this.trigger('changed'); + }, + + // The opposite of `run()`, un-binds all event listeners and intervals + // `run()` Automatically binds a `onunload` event to run this when + // the document is closed. + unload: function() { + if (!this.isRunning()) { return false; } + var app = this; + this.trigger('unload'); + // clear interval + this._location_proxy.unbind(); + // unbind form submits + this.$element().unbind('submit').removeClass(app.eventNamespace()); + // unbind all events + $.each(this.listeners.toHash() , function(name, listeners) { + $.each(listeners, function(i, listener_callback) { + app._unlisten(name, listener_callback); + }); + }); + this._running = false; + return this; + }, + + // Will bind a single callback function to every event that is already + // being listened to in the app. This includes all the `APP_EVENTS` + // as well as any custom events defined with `bind()`. + // + // Used internally for debug logging. + bindToAllEvents: function(callback) { + var app = this; + // bind to the APP_EVENTS first + $.each(this.APP_EVENTS, function(i, e) { + app.bind(e, callback); + }); + // next, bind to listener names (only if they dont exist in APP_EVENTS) + $.each(this.listeners.keys(true), function(i, name) { + if ($.inArray(name, app.APP_EVENTS) == -1) { + app.bind(name, callback); + } + }); + return this; + }, + + // Returns a copy of the given path with any query string after the hash + // removed. + routablePath: function(path) { + return path.replace(QUERY_STRING_MATCHER, ''); + }, + + // Given a verb and a String path, will return either a route object or false + // if a matching route can be found within the current defined set. + lookupRoute: function(verb, path) { + var app = this, routed = false, i = 0, l, route; + if (typeof this.routes[verb] != 'undefined') { + l = this.routes[verb].length; + for (; i < l; i++) { + route = this.routes[verb][i]; + if (app.routablePath(path).match(route.path)) { + routed = route; + break; + } + } + } + return routed; + }, + + // First, invokes `lookupRoute()` and if a route is found, parses the + // possible URL params and then invokes the route's callback within a new + // `Sammy.EventContext`. If the route can not be found, it calls + // `notFound()`. If `raise_errors` is set to `true` and + // the `error()` has not been overridden, it will throw an actual JS + // error. + // + // You probably will never have to call this directly. + // + // ### Arguments + // + // * `verb` A String for the verb. + // * `path` A String path to lookup. + // * `params` An Object of Params pulled from the URI or passed directly. + // + // ### Returns + // + // Either returns the value returned by the route callback or raises a 404 Not Found error. + // + runRoute: function(verb, path, params, target) { + var app = this, + route = this.lookupRoute(verb, path), + context, + wrapped_route, + arounds, + around, + befores, + before, + callback_args, + path_params, + final_returned; + + this.log('runRoute', [verb, path].join(' ')); + this.trigger('run-route', {verb: verb, path: path, params: params}); + if (typeof params == 'undefined') { params = {}; } + + $.extend(params, this._parseQueryString(path)); + + if (route) { + this.trigger('route-found', {route: route}); + // pull out the params from the path + if ((path_params = route.path.exec(this.routablePath(path))) !== null) { + // first match is the full path + path_params.shift(); + // for each of the matches + $.each(path_params, function(i, param) { + // if theres a matching param name + if (route.param_names[i]) { + // set the name to the match + params[route.param_names[i]] = _decode(param); + } else { + // initialize 'splat' + if (!params.splat) { params.splat = []; } + params.splat.push(_decode(param)); + } + }); + } + + // set event context + context = new this.context_prototype(this, verb, path, params, target); + // ensure arrays + arounds = this.arounds.slice(0); + befores = this.befores.slice(0); + // set the callback args to the context + contents of the splat + callback_args = [context].concat(params.splat); + // wrap the route up with the before filters + wrapped_route = function() { + var returned; + while (befores.length > 0) { + before = befores.shift(); + // check the options + if (app.contextMatchesOptions(context, before[0])) { + returned = before[1].apply(context, [context]); + if (returned === false) { return false; } + } + } + app.last_route = route; + context.trigger('event-context-before', {context: context}); + returned = route.callback.apply(context, callback_args); + context.trigger('event-context-after', {context: context}); + return returned; + }; + $.each(arounds.reverse(), function(i, around) { + var last_wrapped_route = wrapped_route; + wrapped_route = function() { return around.apply(context, [last_wrapped_route]); }; + }); + try { + final_returned = wrapped_route(); + } catch(e) { + this.error(['500 Error', verb, path].join(' '), e); + } + return final_returned; + } else { + return this.notFound(verb, path); + } + }, + + // Matches an object of options against an `EventContext` like object that + // contains `path` and `verb` attributes. Internally Sammy uses this + // for matching `before()` filters against specific options. You can set the + // object to _only_ match certain paths or verbs, or match all paths or verbs _except_ + // those that match the options. + // + // ### Example + // + // var app = $.sammy(), + // context = {verb: 'get', path: '#/mypath'}; + // + // // match against a path string + // app.contextMatchesOptions(context, '#/mypath'); //=> true + // app.contextMatchesOptions(context, '#/otherpath'); //=> false + // // equivalent to + // app.contextMatchesOptions(context, {only: {path:'#/mypath'}}); //=> true + // app.contextMatchesOptions(context, {only: {path:'#/otherpath'}}); //=> false + // // match against a path regexp + // app.contextMatchesOptions(context, /path/); //=> true + // app.contextMatchesOptions(context, /^path/); //=> false + // // match only a verb + // app.contextMatchesOptions(context, {only: {verb:'get'}}); //=> true + // app.contextMatchesOptions(context, {only: {verb:'post'}}); //=> false + // // match all except a verb + // app.contextMatchesOptions(context, {except: {verb:'post'}}); //=> true + // app.contextMatchesOptions(context, {except: {verb:'get'}}); //=> false + // // match all except a path + // app.contextMatchesOptions(context, {except: {path:'#/otherpath'}}); //=> true + // app.contextMatchesOptions(context, {except: {path:'#/mypath'}}); //=> false + // // match multiple paths + // app.contextMatchesOptions(context, {path: ['#/mypath', '#/otherpath']}); //=> true + // app.contextMatchesOptions(context, {path: ['#/otherpath', '#/thirdpath']}); //=> false + // // equivalent to + // app.contextMatchesOptions(context, {only: {path: ['#/mypath', '#/otherpath']}}); //=> true + // app.contextMatchesOptions(context, {only: {path: ['#/otherpath', '#/thirdpath']}}); //=> false + // // match all except multiple paths + // app.contextMatchesOptions(context, {except: {path: ['#/mypath', '#/otherpath']}}); //=> false + // app.contextMatchesOptions(context, {except: {path: ['#/otherpath', '#/thirdpath']}}); //=> true + // + contextMatchesOptions: function(context, match_options, positive) { + var options = match_options; + // normalize options + if (typeof options === 'string' || _isRegExp(options)) { + options = {path: options}; + } + if (typeof positive === 'undefined') { + positive = true; + } + // empty options always match + if ($.isEmptyObject(options)) { + return true; + } + // Do we have to match against multiple paths? + if (_isArray(options.path)){ + var results, numopt, opts; + results = []; + for (numopt in options.path){ + opts = $.extend({}, options, {path: options.path[numopt]}); + results.push(this.contextMatchesOptions(context, opts)); + } + var matched = $.inArray(true, results) > -1 ? true : false; + return positive ? matched : !matched; + } + if (options.only) { + return this.contextMatchesOptions(context, options.only, true); + } else if (options.except) { + return this.contextMatchesOptions(context, options.except, false); + } + var path_matched = true, verb_matched = true; + if (options.path) { + if (!_isRegExp(options.path)) { + options.path = new RegExp(options.path.toString() + '$'); + } + path_matched = options.path.test(context.path); + } + if (options.verb) { + if(typeof options.verb === 'string') { + verb_matched = options.verb === context.verb; + } else { + verb_matched = options.verb.indexOf(context.verb) > -1; + } + } + return positive ? (verb_matched && path_matched) : !(verb_matched && path_matched); + }, + + + // Delegates to the `location_proxy` to get the current location. + // See `Sammy.DefaultLocationProxy` for more info on location proxies. + getLocation: function() { + return this._location_proxy.getLocation(); + }, + + // Delegates to the `location_proxy` to set the current location. + // See `Sammy.DefaultLocationProxy` for more info on location proxies. + // + // ### Arguments + // + // * `new_location` A new location string (e.g. '#/') + // + setLocation: function(new_location) { + return this._location_proxy.setLocation(new_location); + }, + + // Swaps the content of `$element()` with `content` + // You can override this method to provide an alternate swap behavior + // for `EventContext.partial()`. + // + // ### Example + // + // var app = $.sammy(function() { + // + // // implements a 'fade out'/'fade in' + // this.swap = function(content, callback) { + // var context = this; + // context.$element().fadeOut('slow', function() { + // context.$element().html(content); + // context.$element().fadeIn('slow', function() { + // if (callback) { + // callback.apply(); + // } + // }); + // }); + // }; + // + // }); + // + swap: function(content, callback) { + var $el = this.$element().html(content); + if (_isFunction(callback)) { callback(content); } + return $el; + }, + + // a simple global cache for templates. Uses the same semantics as + // `Sammy.Cache` and `Sammy.Storage` so can easily be replaced with + // a persistent storage that lasts beyond the current request. + templateCache: function(key, value) { + if (typeof value != 'undefined') { + return _template_cache[key] = value; + } else { + return _template_cache[key]; + } + }, + + // clear the templateCache + clearTemplateCache: function() { + return _template_cache = {}; + }, + + // This throws a '404 Not Found' error by invoking `error()`. + // Override this method or `error()` to provide custom + // 404 behavior (i.e redirecting to / or showing a warning) + notFound: function(verb, path) { + var ret = this.error(['404 Not Found', verb, path].join(' ')); + return (verb === 'get') ? ret : true; + }, + + // The base error handler takes a string `message` and an `Error` + // object. If `raise_errors` is set to `true` on the app level, + // this will re-throw the error to the browser. Otherwise it will send the error + // to `log()`. Override this method to provide custom error handling + // e.g logging to a server side component or displaying some feedback to the + // user. + error: function(message, original_error) { + if (!original_error) { original_error = new Error(); } + original_error.message = [message, original_error.message].join(' '); + this.trigger('error', {message: original_error.message, error: original_error}); + if (this.raise_errors) { + throw(original_error); + } else { + this.log(original_error.message, original_error); + } + }, + + _checkLocation: function() { + var location, returned; + // get current location + location = this.getLocation(); + // compare to see if hash has changed + if (!this.last_location || this.last_location[0] != 'get' || this.last_location[1] != location) { + // reset last location + this.last_location = ['get', location]; + // lookup route for current hash + returned = this.runRoute('get', location); + } + return returned; + }, + + _getFormVerb: function(form) { + var $form = $(form), verb, $_method; + $_method = $form.find('input[name="_method"]'); + if ($_method.length > 0) { verb = $_method.val(); } + if (!verb) { verb = $form[0].getAttribute('method'); } + if (!verb || verb == '') { verb = 'get'; } + return $.trim(verb.toString().toLowerCase()); + }, + + _checkFormSubmission: function(form) { + var $form, path, verb, params, returned; + this.trigger('check-form-submission', {form: form}); + $form = $(form); + path = $form.attr('action') || ''; + verb = this._getFormVerb($form); + this.log('_checkFormSubmission', $form, path, verb); + if (verb === 'get') { + params = this._serializeFormParams($form); + if (params !== '') { path += '?' + params; } + this.setLocation(path); + returned = false; + } else { + params = $.extend({}, this._parseFormParams($form)); + returned = this.runRoute(verb, path, params, form.get(0)); + } + return (typeof returned == 'undefined') ? false : returned; + }, + + _serializeFormParams: function($form) { + var queryString = "", + fields = $form.serializeArray(), + i; + if (fields.length > 0) { + queryString = this._encodeFormPair(fields[0].name, fields[0].value); + for (i = 1; i < fields.length; i++) { + queryString = queryString + "&" + this._encodeFormPair(fields[i].name, fields[i].value); + } + } + return queryString; + }, + + _encodeFormPair: function(name, value){ + return _encode(name) + "=" + _encode(value); + }, + + _parseFormParams: function($form) { + var params = {}, + form_fields = $form.serializeArray(), + i; + for (i = 0; i < form_fields.length; i++) { + params = this._parseParamPair(params, form_fields[i].name, form_fields[i].value); + } + return params; + }, + + _parseQueryString: function(path) { + var params = {}, parts, pairs, pair, i; + + parts = path.match(QUERY_STRING_MATCHER); + if (parts && parts[1]) { + pairs = parts[1].split('&'); + for (i = 0; i < pairs.length; i++) { + pair = pairs[i].split('='); + params = this._parseParamPair(params, _decode(pair[0]), _decode(pair[1] || "")); + } + } + return params; + }, + + _parseParamPair: function(params, key, value) { + if (typeof params[key] !== 'undefined') { + if (_isArray(params[key])) { + params[key].push(value); + } else { + params[key] = [params[key], value]; + } + } else { + params[key] = value; + } + return params; + }, + + _listen: function(name, callback) { + return this.$element().bind([name, this.eventNamespace()].join('.'), callback); + }, + + _unlisten: function(name, callback) { + return this.$element().unbind([name, this.eventNamespace()].join('.'), callback); + } + + }); + + // `Sammy.RenderContext` is an object that makes sequential template loading, + // rendering and interpolation seamless even when dealing with asynchronous + // operations. + // + // `RenderContext` objects are not usually created directly, rather they are + // instantiated from an `Sammy.EventContext` by using `render()`, `load()` or + // `partial()` which all return `RenderContext` objects. + // + // `RenderContext` methods always returns a modified `RenderContext` + // for chaining (like jQuery itself). + // + // The core magic is in the `then()` method which puts the callback passed as + // an argument into a queue to be executed once the previous callback is complete. + // All the methods of `RenderContext` are wrapped in `then()` which allows you + // to queue up methods by chaining, but maintaining a guaranteed execution order + // even with remote calls to fetch templates. + // + Sammy.RenderContext = function(event_context) { + this.event_context = event_context; + this.callbacks = []; + this.previous_content = null; + this.content = null; + this.next_engine = false; + this.waiting = false; + }; + + Sammy.RenderContext.prototype = $.extend({}, Sammy.Object.prototype, { + + // The "core" of the `RenderContext` object, adds the `callback` to the + // queue. If the context is `waiting` (meaning an async operation is happening) + // then the callback will be executed in order, once the other operations are + // complete. If there is no currently executing operation, the `callback` + // is executed immediately. + // + // The value returned from the callback is stored in `content` for the + // subsequent operation. If you return `false`, the queue will pause, and + // the next callback in the queue will not be executed until `next()` is + // called. This allows for the guaranteed order of execution while working + // with async operations. + // + // If then() is passed a string instead of a function, the string is looked + // up as a helper method on the event context. + // + // ### Example + // + // this.get('#/', function() { + // // initialize the RenderContext + // // Even though `load()` executes async, the next `then()` + // // wont execute until the load finishes + // this.load('myfile.txt') + // .then(function(content) { + // // the first argument to then is the content of the + // // prev operation + // $('#main').html(content); + // }); + // }); + // + then: function(callback) { + if (!_isFunction(callback)) { + // if a string is passed to then, assume we want to call + // a helper on the event context in its context + if (typeof callback === 'string' && callback in this.event_context) { + var helper = this.event_context[callback]; + callback = function(content) { + return helper.apply(this.event_context, [content]); + }; + } else { + return this; + } + } + var context = this; + if (this.waiting) { + this.callbacks.push(callback); + } else { + this.wait(); + window.setTimeout(function() { + var returned = callback.apply(context, [context.content, context.previous_content]); + if (returned !== false) { + context.next(returned); + } + }, 0); + } + return this; + }, + + // Pause the `RenderContext` queue. Combined with `next()` allows for async + // operations. + // + // ### Example + // + // this.get('#/', function() { + // this.load('mytext.json') + // .then(function(content) { + // var context = this, + // data = JSON.parse(content); + // // pause execution + // context.wait(); + // // post to a url + // $.post(data.url, {}, function(response) { + // context.next(JSON.parse(response)); + // }); + // }) + // .then(function(data) { + // // data is json from the previous post + // $('#message').text(data.status); + // }); + // }); + wait: function() { + this.waiting = true; + }, + + // Resume the queue, setting `content` to be used in the next operation. + // See `wait()` for an example. + next: function(content) { + this.waiting = false; + if (typeof content !== 'undefined') { + this.previous_content = this.content; + this.content = content; + } + if (this.callbacks.length > 0) { + this.then(this.callbacks.shift()); + } + }, + + // Load a template into the context. + // The `location` can either be a string specifying the remote path to the + // file, a jQuery object, or a DOM element. + // + // No interpolation happens by default, the content is stored in + // `content`. + // + // In the case of a path, unless the option `{cache: false}` is passed the + // data is stored in the app's `templateCache()`. + // + // If a jQuery or DOM object is passed the `innerHTML` of the node is pulled in. + // This is useful for nesting templates as part of the initial page load wrapped + // in invisible elements or `<script>` tags. With template paths, the template + // engine is looked up by the extension. For DOM/jQuery embedded templates, + // this isnt possible, so there are a couple of options: + // + // * pass an `{engine:}` option. + // * define the engine in the `data-engine` attribute of the passed node. + // * just store the raw template data and use `interpolate()` manually + // + // If a `callback` is passed it is executed after the template load. + load: function(location, options, callback) { + var context = this; + return this.then(function() { + var should_cache, cached, is_json, location_array; + if (_isFunction(options)) { + callback = options; + options = {}; + } else { + options = $.extend({}, options); + } + if (callback) { this.then(callback); } + if (typeof location === 'string') { + // it's a path + is_json = (location.match(/\.json$/) || options.json); + should_cache = is_json ? options.cache === true : options.cache !== false; + context.next_engine = context.event_context.engineFor(location); + delete options.cache; + delete options.json; + if (options.engine) { + context.next_engine = options.engine; + delete options.engine; + } + if (should_cache && (cached = this.event_context.app.templateCache(location))) { + return cached; + } + this.wait(); + $.ajax($.extend({ + url: location, + data: {}, + dataType: is_json ? 'json' : 'text', + type: 'get', + success: function(data) { + if (should_cache) { + context.event_context.app.templateCache(location, data); + } + context.next(data); + } + }, options)); + return false; + } else { + // it's a dom/jQuery + if (location.nodeType) { + return location.innerHTML; + } + if (location.selector) { + // it's a jQuery + context.next_engine = location.attr('data-engine'); + if (options.clone === false) { + return location.remove()[0].innerHTML.toString(); + } else { + return location[0].innerHTML.toString(); + } + } + } + }); + }, + + // Load partials + // + // ### Example + // + // this.loadPartials({mypartial: '/path/to/partial'}); + // + loadPartials: function(partials) { + var name; + if(partials) { + this.partials = this.partials || {}; + for(name in partials) { + (function(context, name) { + context.load(partials[name]) + .then(function(template) { + this.partials[name] = template; + }); + })(this, name); + } + } + return this; + }, + + // `load()` a template and then `interpolate()` it with data. + // + // can be called with multiple different signatures: + // + // this.render(callback); + // this.render('/location'); + // this.render('/location', {some: data}); + // this.render('/location', callback); + // this.render('/location', {some: data}, callback); + // this.render('/location', {some: data}, {my: partials}); + // this.render('/location', callback, {my: partials}); + // this.render('/location', {some: data}, callback, {my: partials}); + // + // ### Example + // + // this.get('#/', function() { + // this.render('mytemplate.template', {name: 'test'}); + // }); + // + render: function(location, data, callback, partials) { + if (_isFunction(location) && !data) { + // invoked as render(callback) + return this.then(location); + } else { + if(_isFunction(data)) { + // invoked as render(location, callback, [partials]) + partials = callback; + callback = data; + data = null; + } else if(callback && !_isFunction(callback)) { + // invoked as render(location, data, partials) + partials = callback; + callback = null; + } + + return this.loadPartials(partials) + .load(location) + .interpolate(data, location) + .then(callback); + } + }, + + // `render()` the `location` with `data` and then `swap()` the + // app's `$element` with the rendered content. + partial: function(location, data, callback, partials) { + if (_isFunction(callback)) { + // invoked as partial(location, data, callback, [partials]) + return this.render(location, data, partials).swap(callback); + } else if (_isFunction(data)) { + // invoked as partial(location, callback, [partials]) + return this.render(location, {}, callback).swap(data); + } else { + // invoked as partial(location, data, [partials]) + return this.render(location, data, callback).swap(); + } + }, + + // defers the call of function to occur in order of the render queue. + // The function can accept any number of arguments as long as the last + // argument is a callback function. This is useful for putting arbitrary + // asynchronous functions into the queue. The content passed to the + // callback is passed as `content` to the next item in the queue. + // + // ### Example + // + // this.send($.getJSON, '/app.json') + // .then(function(json) { + // $('#message).text(json['message']); + // }); + // + // + send: function() { + var context = this, + args = _makeArray(arguments), + fun = args.shift(); + + if (_isArray(args[0])) { args = args[0]; } + + return this.then(function(content) { + args.push(function(response) { context.next(response); }); + context.wait(); + fun.apply(fun, args); + return false; + }); + }, + + // iterates over an array, applying the callback for each item item. the + // callback takes the same style of arguments as `jQuery.each()` (index, item). + // The return value of each callback is collected as a single string and stored + // as `content` to be used in the next iteration of the `RenderContext`. + collect: function(array, callback, now) { + var context = this; + var coll = function() { + if (_isFunction(array)) { + callback = array; + array = this.content; + } + var contents = [], doms = false; + $.each(array, function(i, item) { + var returned = callback.apply(context, [i, item]); + if (returned.jquery && returned.length == 1) { + returned = returned[0]; + doms = true; + } + contents.push(returned); + return returned; + }); + return doms ? contents : contents.join(''); + }; + return now ? coll() : this.then(coll); + }, + + // loads a template, and then interpolates it for each item in the `data` + // array. If a callback is passed, it will call the callback with each + // item in the array _after_ interpolation + renderEach: function(location, name, data, callback) { + if (_isArray(name)) { + callback = data; + data = name; + name = null; + } + return this.load(location).then(function(content) { + var rctx = this; + if (!data) { + data = _isArray(this.previous_content) ? this.previous_content : []; + } + if (callback) { + $.each(data, function(i, value) { + var idata = {}, engine = this.next_engine || location; + name ? (idata[name] = value) : (idata = value); + callback(value, rctx.event_context.interpolate(content, idata, engine)); + }); + } else { + return this.collect(data, function(i, value) { + var idata = {}, engine = this.next_engine || location; + name ? (idata[name] = value) : (idata = value); + return this.event_context.interpolate(content, idata, engine); + }, true); + } + }); + }, + + // uses the previous loaded `content` and the `data` object to interpolate + // a template. `engine` defines the templating/interpolation method/engine + // that should be used. If `engine` is not passed, the `next_engine` is + // used. If `retain` is `true`, the final interpolated data is appended to + // the `previous_content` instead of just replacing it. + interpolate: function(data, engine, retain) { + var context = this; + return this.then(function(content, prev) { + if (!data && prev) { data = prev; } + if (this.next_engine) { + engine = this.next_engine; + this.next_engine = false; + } + var rendered = context.event_context.interpolate(content, data, engine, this.partials); + return retain ? prev + rendered : rendered; + }); + }, + + // Swap the return contents ensuring order. See `Application#swap` + swap: function(callback) { + return this.then(function(content) { + this.event_context.swap(content, callback); + return content; + }).trigger('changed', {}); + }, + + // Same usage as `jQuery.fn.appendTo()` but uses `then()` to ensure order + appendTo: function(selector) { + return this.then(function(content) { + $(selector).append(content); + }).trigger('changed', {}); + }, + + // Same usage as `jQuery.fn.prependTo()` but uses `then()` to ensure order + prependTo: function(selector) { + return this.then(function(content) { + $(selector).prepend(content); + }).trigger('changed', {}); + }, + + // Replaces the `$(selector)` using `html()` with the previously loaded + // `content` + replace: function(selector) { + return this.then(function(content) { + $(selector).html(content); + }).trigger('changed', {}); + }, + + // trigger the event in the order of the event context. Same semantics + // as `Sammy.EventContext#trigger()`. If data is omitted, `content` + // is sent as `{content: content}` + trigger: function(name, data) { + return this.then(function(content) { + if (typeof data == 'undefined') { data = {content: content}; } + this.event_context.trigger(name, data); + return content; + }); + } + + }); + + // `Sammy.EventContext` objects are created every time a route is run or a + // bound event is triggered. The callbacks for these events are evaluated within a `Sammy.EventContext` + // This within these callbacks the special methods of `EventContext` are available. + // + // ### Example + // + // $.sammy(function() { + // // The context here is this Sammy.Application + // this.get('#/:name', function() { + // // The context here is a new Sammy.EventContext + // if (this.params['name'] == 'sammy') { + // this.partial('name.html.erb', {name: 'Sammy'}); + // } else { + // this.redirect('#/somewhere-else') + // } + // }); + // }); + // + // Initialize a new EventContext + // + // ### Arguments + // + // * `app` The `Sammy.Application` this event is called within. + // * `verb` The verb invoked to run this context/route. + // * `path` The string path invoked to run this context/route. + // * `params` An Object of optional params to pass to the context. Is converted + // to a `Sammy.Object`. + // * `target` a DOM element that the event that holds this context originates + // from. For post, put and del routes, this is the form element that triggered + // the route. + // + Sammy.EventContext = function(app, verb, path, params, target) { + this.app = app; + this.verb = verb; + this.path = path; + this.params = new Sammy.Object(params); + this.target = target; + }; + + Sammy.EventContext.prototype = $.extend({}, Sammy.Object.prototype, { + + // A shortcut to the app's `$element()` + $element: function() { + return this.app.$element(_makeArray(arguments).shift()); + }, + + // Look up a templating engine within the current app and context. + // `engine` can be one of the following: + // + // * a function: should conform to `function(content, data) { return interpolated; }` + // * a template path: 'template.ejs', looks up the extension to match to + // the `ejs()` helper + // * a string referring to the helper: "mustache" => `mustache()` + // + // If no engine is found, use the app's default `template_engine` + // + engineFor: function(engine) { + var context = this, engine_match; + // if path is actually an engine function just return it + if (_isFunction(engine)) { return engine; } + // lookup engine name by path extension + engine = (engine || context.app.template_engine).toString(); + if ((engine_match = engine.match(/\.([^\.\?\#]+)$/))) { + engine = engine_match[1]; + } + // set the engine to the default template engine if no match is found + if (engine && _isFunction(context[engine])) { + return context[engine]; + } + + if (context.app.template_engine) { + return this.engineFor(context.app.template_engine); + } + return function(content, data) { return content; }; + }, + + // using the template `engine` found with `engineFor()`, interpolate the + // `data` into `content` + interpolate: function(content, data, engine, partials) { + return this.engineFor(engine).apply(this, [content, data, partials]); + }, + + // Create and return a `Sammy.RenderContext` calling `render()` on it. + // Loads the template and interpolate the data, however does not actual + // place it in the DOM. + // + // ### Example + // + // // mytemplate.mustache <div class="name">{{name}}</div> + // render('mytemplate.mustache', {name: 'quirkey'}); + // // sets the `content` to <div class="name">quirkey</div> + // render('mytemplate.mustache', {name: 'quirkey'}) + // .appendTo('ul'); + // // appends the rendered content to $('ul') + // + render: function(location, data, callback, partials) { + return new Sammy.RenderContext(this).render(location, data, callback, partials); + }, + + // Create and return a `Sammy.RenderContext` calling `renderEach()` on it. + // Loads the template and interpolates the data for each item, + // however does not actual place it in the DOM. + // + // ### Example + // + // // mytemplate.mustache <div class="name">{{name}}</div> + // renderEach('mytemplate.mustache', [{name: 'quirkey'}, {name: 'endor'}]) + // // sets the `content` to <div class="name">quirkey</div><div class="name">endor</div> + // renderEach('mytemplate.mustache', [{name: 'quirkey'}, {name: 'endor'}]).appendTo('ul'); + // // appends the rendered content to $('ul') + // + renderEach: function(location, name, data, callback) { + return new Sammy.RenderContext(this).renderEach(location, name, data, callback); + }, + + // create a new `Sammy.RenderContext` calling `load()` with `location` and + // `options`. Called without interpolation or placement, this allows for + // preloading/caching the templates. + load: function(location, options, callback) { + return new Sammy.RenderContext(this).load(location, options, callback); + }, + + // `render()` the `location` with `data` and then `swap()` the + // app's `$element` with the rendered content. + partial: function(location, data, callback, partials) { + return new Sammy.RenderContext(this).partial(location, data, callback, partials); + }, + + // create a new `Sammy.RenderContext` calling `send()` with an arbitrary + // function + send: function() { + var rctx = new Sammy.RenderContext(this); + return rctx.send.apply(rctx, arguments); + }, + + // Changes the location of the current window. If `to` begins with + // '#' it only changes the document's hash. If passed more than 1 argument + // redirect will join them together with forward slashes. + // + // ### Example + // + // redirect('#/other/route'); + // // equivalent to + // redirect('#', 'other', 'route'); + // + redirect: function() { + var to, args = _makeArray(arguments), + current_location = this.app.getLocation(), + l = args.length; + if (l > 1) { + var i = 0, paths = [], pairs = [], params = {}, has_params = false; + for (; i < l; i++) { + if (typeof args[i] == 'string') { + paths.push(args[i]); + } else { + $.extend(params, args[i]); + has_params = true; + } + } + to = paths.join('/'); + if (has_params) { + for (var k in params) { + pairs.push(this.app._encodeFormPair(k, params[k])); + } + to += '?' + pairs.join('&'); + } + } else { + to = args[0]; + } + this.trigger('redirect', {to: to}); + this.app.last_location = [this.verb, this.path]; + this.app.setLocation(to); + if (new RegExp(to).test(current_location)) { + this.app.trigger('location-changed'); + } + }, + + // Triggers events on `app` within the current context. + trigger: function(name, data) { + if (typeof data == 'undefined') { data = {}; } + if (!data.context) { data.context = this; } + return this.app.trigger(name, data); + }, + + // A shortcut to app's `eventNamespace()` + eventNamespace: function() { + return this.app.eventNamespace(); + }, + + // A shortcut to app's `swap()` + swap: function(contents, callback) { + return this.app.swap(contents, callback); + }, + + // Raises a possible `notFound()` error for the current path. + notFound: function() { + return this.app.notFound(this.verb, this.path); + }, + + // Default JSON parsing uses jQuery's `parseJSON()`. Include `Sammy.JSON` + // plugin for the more conformant "crockford special". + json: function(string) { + return $.parseJSON(string); + }, + + // //=> Sammy.EventContext: get #/ {} + toString: function() { + return "Sammy.EventContext: " + [this.verb, this.path, this.params].join(' '); + } + + }); + + return Sammy; +}); +})(jQuery, window); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/select2.min-3.2.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/select2.min-3.2.js new file mode 100755 index 000000000..152373565 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/select2.min-3.2.js @@ -0,0 +1,82 @@ +/* +Copyright 2012 Igor Vaynberg + +Version: 3.2 Timestamp: Mon Sep 10 10:38:04 PDT 2012 + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in +compliance with the License. You may obtain a copy of the License in the LICENSE file, or at: + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is +distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and limitations under the License. +*/ +(function(e){"undefined"==typeof e.fn.each2&&e.fn.extend({each2:function(g){for(var i=e([0]),m=-1,s=this.length;++m<s&&(i.context=i[0]=this[m])&&!1!==g.call(i[0],m,i););return this}})})(jQuery); +(function(e,g){function i(a,b){var c=0,d=b.length,j;if("undefined"===typeof a)return-1;if(a.constructor===String)for(;c<d;c+=1){if(0===a.localeCompare(b[c]))return c}else for(;c<d;c+=1)if(j=b[c],j.constructor===String){if(0===j.localeCompare(a))return c}else if(j===a)return c;return-1}function m(a,b){return a===b?!0:a===g||b===g||null===a||null===b?!1:a.constructor===String?0===a.localeCompare(b):b.constructor===String?0===b.localeCompare(a):!1}function s(a,b){var c,d,j;if(null===a||1>a.length)return[]; +c=a.split(b);d=0;for(j=c.length;d<j;d+=1)c[d]=e.trim(c[d]);return c}function A(a,b,c){var c=c||g,d;return function(){var j=arguments;window.clearTimeout(d);d=window.setTimeout(function(){b.apply(c,j)},a)}}function l(a){a.preventDefault();a.stopPropagation()}function B(a,b,c){var d=a.toUpperCase().indexOf(b.toUpperCase()),b=b.length;0>d?c.push(a):(c.push(a.substring(0,d)),c.push("<span class='select2-match'>"),c.push(a.substring(d,d+b)),c.push("</span>"),c.push(a.substring(d+b,a.length)))}function C(a){var b, +c=0,d=null,j=a.quietMillis||100;return function(h){window.clearTimeout(b);b=window.setTimeout(function(){var b=c+=1,j=a.data,n=a.transport||e.ajax,f=a.traditional||!1,g=a.type||"GET",j=j.call(this,h.term,h.page,h.context);null!==d&&d.abort();d=n.call(null,{url:a.url,dataType:a.dataType,data:j,type:g,traditional:f,success:function(d){b<c||(d=a.results(d,h.page),h.callback(d))}})},j)}}function D(a){var b=a,c,d=function(a){return""+a.text};e.isArray(b)||(d=b.text,e.isFunction(d)||(c=b.text,d=function(a){return a[c]}), +b=b.results);return function(a){var c=a.term,f={results:[]},k;if(c==="")a.callback({results:b});else{k=function(b,f){var g,t,b=b[0];if(b.children){g={};for(t in b)b.hasOwnProperty(t)&&(g[t]=b[t]);g.children=[];e(b.children).each2(function(a,b){k(b,g.children)});g.children.length&&f.push(g)}else a.matcher(c,d(b))&&f.push(b)};e(b).each2(function(a,b){k(b,f.results)});a.callback(f)}}}function E(a){return e.isFunction(a)?a:function(b){var c=b.term,d={results:[]};e(a).each(function(){var a=this.text!== +g,e=a?this.text:this;if(""===c||b.matcher(c,e))d.results.push(a?this:{id:this,text:this})});b.callback(d)}}function u(a){if(e.isFunction(a))return!0;if(!a)return!1;throw Error("formatterName must be a function or a falsy value");}function v(a){return e.isFunction(a)?a():a}function F(a){var b=0;e.each(a,function(a,d){d.children?b+=F(d.children):b++});return b}function H(a,b,c,d){var e=a,h=!1,f,k,n,o;if(!d.createSearchChoice||!d.tokenSeparators||1>d.tokenSeparators.length)return g;for(;;){h=-1;k=0; +for(n=d.tokenSeparators.length;k<n&&!(o=d.tokenSeparators[k],h=a.indexOf(o),0<=h);k++);if(0>h)break;f=a.substring(0,h);a=a.substring(h+o.length);if(0<f.length&&(f=d.createSearchChoice(f,b),f!==g&&null!==f&&d.id(f)!==g&&null!==d.id(f))){h=!1;k=0;for(n=b.length;k<n;k++)if(m(d.id(f),d.id(b[k]))){h=!0;break}h||c(f)}}if(0!=e.localeCompare(a))return a}function x(a,b){var c=function(){};c.prototype=new a;c.prototype.constructor=c;c.prototype.parent=a.prototype;c.prototype=e.extend(c.prototype,b);return c} +if(window.Select2===g){var f,w,y,z,G,q;f={TAB:9,ENTER:13,ESC:27,SPACE:32,LEFT:37,UP:38,RIGHT:39,DOWN:40,SHIFT:16,CTRL:17,ALT:18,PAGE_UP:33,PAGE_DOWN:34,HOME:36,END:35,BACKSPACE:8,DELETE:46,isArrow:function(a){a=a.which?a.which:a;switch(a){case f.LEFT:case f.RIGHT:case f.UP:case f.DOWN:return!0}return!1},isControl:function(a){switch(a.which){case f.SHIFT:case f.CTRL:case f.ALT:return!0}return a.metaKey?!0:!1},isFunctionKey:function(a){a=a.which?a.which:a;return 112<=a&&123>=a}};var I=1;G=function(){return I++}; +e(document).delegate("body","mousemove",function(a){e.data(document,"select2-lastpos",{x:a.pageX,y:a.pageY})});e(document).ready(function(){e(document).delegate("body","mousedown touchend",function(a){var b=e(a.target).closest("div.select2-container").get(0),c;b?e(document).find("div.select2-container-active").each(function(){this!==b&&e(this).data("select2").blur()}):(b=e(a.target).closest("div.select2-drop").get(0),e(document).find("div.select2-drop-active").each(function(){this!==b&&e(this).data("select2").blur()})); +b=e(a.target);c=b.attr("for");"LABEL"===a.target.tagName&&(c&&0<c.length)&&(b=e("#"+c),b=b.data("select2"),b!==g&&(b.focus(),a.preventDefault()))})});w=x(Object,{bind:function(a){var b=this;return function(){a.apply(b,arguments)}},init:function(a){var b,c;this.opts=a=this.prepareOpts(a);this.id=a.id;a.element.data("select2")!==g&&null!==a.element.data("select2")&&this.destroy();this.enabled=!0;this.container=this.createContainer();this.containerId="s2id_"+(a.element.attr("id")||"autogen"+G());this.containerSelector= +"#"+this.containerId.replace(/([;&,\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g,"\\$1");this.container.attr("id",this.containerId);var d=!1,j;this.body=function(){!1===d&&(j=a.element.closest("body"),d=!0);return j};a.element.attr("class")!==g&&this.container.addClass(a.element.attr("class").replace(/validate\[[\S ]+] ?/,""));this.container.css(v(a.containerCss));this.container.addClass(v(a.containerCssClass));this.opts.element.data("select2",this).hide().before(this.container);this.container.data("select2", +this);this.dropdown=this.container.find(".select2-drop");this.dropdown.addClass(v(a.dropdownCssClass));this.dropdown.data("select2",this);this.results=b=this.container.find(".select2-results");this.search=c=this.container.find("input.select2-input");c.attr("tabIndex",this.opts.element.attr("tabIndex"));this.resultsPage=0;this.context=null;this.initContainer();this.initContainerWidth();this.results.bind("mousemove",function(a){var b=e.data(document,"select2-lastpos");(b===g||b.x!==a.pageX||b.y!==a.pageY)&& +e(a.target).trigger("mousemove-filtered",a)});this.dropdown.delegate(".select2-results","mousemove-filtered",this.bind(this.highlightUnderEvent));var h=this.results,f=A(80,function(a){h.trigger("scroll-debounced",a)});h.bind("scroll",function(a){0<=i(a.target,h.get())&&f(a)});this.dropdown.delegate(".select2-results","scroll-debounced",this.bind(this.loadMoreIfNeeded));e.fn.mousewheel&&b.mousewheel(function(a,c,d,e){c=b.scrollTop();0<e&&0>=c-e?(b.scrollTop(0),l(a)):0>e&&b.get(0).scrollHeight-b.scrollTop()+ +e<=b.height()&&(b.scrollTop(b.get(0).scrollHeight-b.height()),l(a))});c.bind("keydown",function(){e.data(c,"keyup-change-value")===g&&e.data(c,"keyup-change-value",c.val())});c.bind("keyup",function(){var a=e.data(c,"keyup-change-value");a!==g&&c.val()!==a&&(e.removeData(c,"keyup-change-value"),c.trigger("keyup-change"))});c.bind("keyup-change",this.bind(this.updateResults));c.bind("focus",function(){c.addClass("select2-focused");" "===c.val()&&c.val("")});c.bind("blur",function(){c.removeClass("select2-focused")}); +this.dropdown.delegate(".select2-results","mouseup",this.bind(function(a){0<e(a.target).closest(".select2-result-selectable:not(.select2-disabled)").length?(this.highlightUnderEvent(a),this.selectHighlighted(a)):this.focusSearch();l(a)}));this.dropdown.bind("click mouseup mousedown",function(a){a.stopPropagation()});e.isFunction(this.opts.initSelection)&&(this.initSelection(),this.monitorSource());(a.element.is(":disabled")||a.element.is("[readonly='readonly']"))&&this.disable()},destroy:function(){var a= +this.opts.element.data("select2");a!==g&&(a.container.remove(),a.dropdown.remove(),a.opts.element.removeData("select2").unbind(".select2").show())},prepareOpts:function(a){var b,c,d;b=a.element;"select"===b.get(0).tagName.toLowerCase()&&(this.select=c=a.element);c&&e.each("id multiple ajax query createSearchChoice initSelection data tags".split(" "),function(){if(this in a)throw Error("Option '"+this+"' is not allowed for Select2 when attached to a <select> element.");});a=e.extend({},{populateResults:function(b, +c,d){var f,n=this.opts.id,o=this;f=function(b,c,j){var h,l,i,m,r,p,q;h=0;for(l=b.length;h<l;h=h+1){i=b[h];m=n(i)!==g;r=i.children&&i.children.length>0;p=e("<li></li>");p.addClass("select2-results-dept-"+j);p.addClass("select2-result");p.addClass(m?"select2-result-selectable":"select2-result-unselectable");r&&p.addClass("select2-result-with-children");p.addClass(o.opts.formatResultCssClass(i));m=e("<div></div>");m.addClass("select2-result-label");q=a.formatResult(i,m,d);q!==g&&m.html(o.opts.escapeMarkup(q)); +p.append(m);if(r){r=e("<ul></ul>");r.addClass("select2-result-sub");f(i.children,r,j+1);p.append(r)}p.data("select2-data",i);c.append(p)}};f(c,b,0)}},e.fn.select2.defaults,a);"function"!==typeof a.id&&(d=a.id,a.id=function(a){return a[d]});if(c)a.query=this.bind(function(a){var c={results:[],more:false},d=a.term,f,n,o;o=function(b,c){var e;if(b.is("option"))a.matcher(d,b.text(),b)&&c.push({id:b.attr("value"),text:b.text(),element:b.get(),css:b.attr("class")});else if(b.is("optgroup")){e={text:b.attr("label"), +children:[],element:b.get(),css:b.attr("class")};b.children().each2(function(a,b){o(b,e.children)});e.children.length>0&&c.push(e)}};f=b.children();if(this.getPlaceholder()!==g&&f.length>0){n=f[0];e(n).text()===""&&(f=f.not(n))}f.each2(function(a,b){o(b,c.results)});a.callback(c)}),a.id=function(a){return a.id},a.formatResultCssClass=function(a){return a.css};else if(!("query"in a))if("ajax"in a){if((c=a.element.data("ajax-url"))&&0<c.length)a.ajax.url=c;a.query=C(a.ajax)}else"data"in a?a.query=D(a.data): +"tags"in a&&(a.query=E(a.tags),a.createSearchChoice=function(a){return{id:a,text:a}},a.initSelection=function(b,c){var d=[];e(s(b.val(),a.separator)).each(function(){var b=this,c=this,j=a.tags;e.isFunction(j)&&(j=j());e(j).each(function(){if(m(this.id,b)){c=this.text;return false}});d.push({id:b,text:c})});c(d)});if("function"!==typeof a.query)throw"query function not defined for Select2 "+a.element.attr("id");return a},monitorSource:function(){this.opts.element.bind("change.select2",this.bind(function(){!0!== +this.opts.element.data("select2-change-triggered")&&this.initSelection()}))},triggerChange:function(a){a=a||{};a=e.extend({},a,{type:"change",val:this.val()});this.opts.element.data("select2-change-triggered",!0);this.opts.element.trigger(a);this.opts.element.data("select2-change-triggered",!1);this.opts.element.click();this.opts.blurOnChange&&this.opts.element.blur()},enable:function(){this.enabled||(this.enabled=!0,this.container.removeClass("select2-container-disabled"))},disable:function(){this.enabled&& +(this.close(),this.enabled=!1,this.container.addClass("select2-container-disabled"))},opened:function(){return this.container.hasClass("select2-dropdown-open")},positionDropdown:function(){var a=this.container.offset(),b=this.container.outerHeight(),c=this.container.outerWidth(),d=this.dropdown.outerHeight(),j=e(window).scrollTop()+document.documentElement.clientHeight,b=a.top+b,f=a.left,j=b+d<=j,g=a.top-d>=this.body().scrollTop(),k=this.dropdown.hasClass("select2-drop-above"),n;"static"!==this.body().css("position")&& +(n=this.body().offset(),b-=n.top,f-=n.left);k?(k=!0,!g&&j&&(k=!1)):(k=!1,!j&&g&&(k=!0));k?(b=a.top-d,this.container.addClass("select2-drop-above"),this.dropdown.addClass("select2-drop-above")):(this.container.removeClass("select2-drop-above"),this.dropdown.removeClass("select2-drop-above"));a=e.extend({top:b,left:f,width:c},v(this.opts.dropdownCss));this.dropdown.css(a)},shouldOpen:function(){var a;if(this.opened())return!1;a=e.Event("open");this.opts.element.trigger(a);return!a.isDefaultPrevented()}, +clearDropdownAlignmentPreference:function(){this.container.removeClass("select2-drop-above");this.dropdown.removeClass("select2-drop-above")},open:function(){if(!this.shouldOpen())return!1;window.setTimeout(this.bind(this.opening),1);return!0},opening:function(){var a=this.containerId,b=this.containerSelector,c="scroll."+a,d="resize."+a;this.container.parents().each(function(){e(this).bind(c,function(){var a=e(b);0==a.length&&e(this).unbind(c);a.select2("close")})});e(window).bind(d,function(){var a= +e(b);0==a.length&&e(window).unbind(d);a.select2("close")});this.clearDropdownAlignmentPreference();" "===this.search.val()&&this.search.val("");this.container.addClass("select2-dropdown-open").addClass("select2-container-active");this.updateResults(!0);this.dropdown[0]!==this.body().children().last()[0]&&this.dropdown.detach().appendTo(this.body());this.dropdown.show();this.positionDropdown();this.dropdown.addClass("select2-drop-active");this.ensureHighlightVisible();this.focusSearch()},close:function(){if(this.opened()){var a= +this;this.container.parents().each(function(){e(this).unbind("scroll."+a.containerId)});e(window).unbind("resize."+this.containerId);this.clearDropdownAlignmentPreference();this.dropdown.hide();this.container.removeClass("select2-dropdown-open").removeClass("select2-container-active");this.results.empty();this.clearSearch();this.opts.element.trigger(e.Event("close"))}},clearSearch:function(){},ensureHighlightVisible:function(){var a=this.results,b,c,d,f;c=this.highlight();0>c||(0==c?a.scrollTop(0): +(b=a.find(".select2-result-selectable"),d=e(b[c]),f=d.offset().top+d.outerHeight(),c===b.length-1&&(b=a.find("li.select2-more-results"),0<b.length&&(f=b.offset().top+b.outerHeight())),b=a.offset().top+a.outerHeight(),f>b&&a.scrollTop(a.scrollTop()+(f-b)),d=d.offset().top-a.offset().top,0>d&&a.scrollTop(a.scrollTop()+d)))},moveHighlight:function(a){for(var b=this.results.find(".select2-result-selectable"),c=this.highlight();-1<c&&c<b.length;){var c=c+a,d=e(b[c]);if(d.hasClass("select2-result-selectable")&& +!d.hasClass("select2-disabled")){this.highlight(c);break}}},highlight:function(a){var b=this.results.find(".select2-result-selectable").not(".select2-disabled");if(0===arguments.length)return i(b.filter(".select2-highlighted")[0],b.get());a>=b.length&&(a=b.length-1);0>a&&(a=0);b.removeClass("select2-highlighted");e(b[a]).addClass("select2-highlighted");this.ensureHighlightVisible()},countSelectableResults:function(){return this.results.find(".select2-result-selectable").not(".select2-disabled").length}, +highlightUnderEvent:function(a){a=e(a.target).closest(".select2-result-selectable");if(0<a.length&&!a.is(".select2-highlighted")){var b=this.results.find(".select2-result-selectable");this.highlight(b.index(a))}else 0==a.length&&this.results.find(".select2-highlighted").removeClass("select2-highlighted")},loadMoreIfNeeded:function(){var a=this.results,b=a.find("li.select2-more-results"),c,d=this.resultsPage+1,e=this,f=this.search.val(),g=this.context;0!==b.length&&(c=b.offset().top-a.offset().top- +a.height(),0>=c&&(b.addClass("select2-active"),this.opts.query({term:f,page:d,context:g,matcher:this.opts.matcher,callback:this.bind(function(c){e.opened()&&(e.opts.populateResults.call(this,a,c.results,{term:f,page:d,context:g}),!0===c.more?(b.detach().appendTo(a).text(e.opts.formatLoadMore(d+1)),window.setTimeout(function(){e.loadMoreIfNeeded()},10)):b.remove(),e.positionDropdown(),e.resultsPage=d)})})))},tokenize:function(){},updateResults:function(a){function b(){f.scrollTop(0);d.removeClass("select2-active"); +k.positionDropdown()}function c(a){f.html(k.opts.escapeMarkup(a));b()}var d=this.search,f=this.results,h=this.opts,i,k=this;if(!(!0!==a&&(!1===this.showSearchInput||!this.opened()))){d.addClass("select2-active");if(1<=h.maximumSelectionSize&&(i=this.data(),e.isArray(i)&&i.length>=h.maximumSelectionSize&&u(h.formatSelectionTooBig,"formatSelectionTooBig"))){c("<li class='select2-selection-limit'>"+h.formatSelectionTooBig(h.maximumSelectionSize)+"</li>");return}d.val().length<h.minimumInputLength&&u(h.formatInputTooShort, +"formatInputTooShort")?c("<li class='select2-no-results'>"+h.formatInputTooShort(d.val(),h.minimumInputLength)+"</li>"):(c("<li class='select2-searching'>"+h.formatSearching()+"</li>"),i=this.tokenize(),i!=g&&null!=i&&d.val(i),this.resultsPage=1,h.query({term:d.val(),page:this.resultsPage,context:null,matcher:h.matcher,callback:this.bind(function(i){var l;this.opened()&&((this.context=i.context===g?null:i.context,this.opts.createSearchChoice&&""!==d.val()&&(l=this.opts.createSearchChoice.call(null, +d.val(),i.results),l!==g&&null!==l&&k.id(l)!==g&&null!==k.id(l)&&0===e(i.results).filter(function(){return m(k.id(this),k.id(l))}).length&&i.results.unshift(l)),0===i.results.length&&u(h.formatNoMatches,"formatNoMatches"))?c("<li class='select2-no-results'>"+h.formatNoMatches(d.val())+"</li>"):(f.empty(),k.opts.populateResults.call(this,f,i.results,{term:d.val(),page:this.resultsPage,context:null}),!0===i.more&&u(h.formatLoadMore,"formatLoadMore")&&(f.append("<li class='select2-more-results'>"+k.opts.escapeMarkup(h.formatLoadMore(this.resultsPage))+ +"</li>"),window.setTimeout(function(){k.loadMoreIfNeeded()},10)),this.postprocessResults(i,a),b()))})}))}},cancel:function(){this.close()},blur:function(){this.close();this.container.removeClass("select2-container-active");this.dropdown.removeClass("select2-drop-active");this.search[0]===document.activeElement&&this.search.blur();this.clearSearch();this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus")},focusSearch:function(){this.search.show();this.search.focus(); +window.setTimeout(this.bind(function(){this.search.show();this.search.focus();this.search.val(this.search.val())}),10)},selectHighlighted:function(){var a=this.highlight(),b=this.results.find(".select2-highlighted").not(".select2-disabled"),c=b.closest(".select2-result-selectable").data("select2-data");c&&(b.addClass("select2-disabled"),this.highlight(a),this.onSelect(c))},getPlaceholder:function(){return this.opts.element.attr("placeholder")||this.opts.element.attr("data-placeholder")||this.opts.element.data("placeholder")|| +this.opts.placeholder},initContainerWidth:function(){var a=function(){var a,c,d,f;if("off"===this.opts.width)return null;if("element"===this.opts.width)return 0===this.opts.element.outerWidth()?"auto":this.opts.element.outerWidth()+"px";if("copy"===this.opts.width||"resolve"===this.opts.width){a=this.opts.element.attr("style");if(a!==g){a=a.split(";");d=0;for(f=a.length;d<f;d+=1)if(c=a[d].replace(/\s/g,"").match(/width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/),null!==c&&1<=c.length)return c[1]}return"resolve"=== +this.opts.width?(a=this.opts.element.css("width"),0<a.indexOf("%")?a:0===this.opts.element.outerWidth()?"auto":this.opts.element.outerWidth()+"px"):null}return e.isFunction(this.opts.width)?this.opts.width():this.opts.width}.call(this);null!==a&&this.container.attr("style","width: "+a)}});y=x(w,{createContainer:function(){return e("<div></div>",{"class":"select2-container"}).html(" <a href='#' onclick='return false;' class='select2-choice'> <span></span><abbr class='select2-search-choice-close' style='display:none;'></abbr> <div><b></b></div></a> <div class='select2-drop select2-offscreen'> <div class='select2-search'> <input type='text' autocomplete='off' class='select2-input'/> </div> <ul class='select2-results'> </ul></div>")}, +opening:function(){this.search.show();this.parent.opening.apply(this,arguments);this.dropdown.removeClass("select2-offscreen")},close:function(){this.opened()&&(this.parent.close.apply(this,arguments),this.dropdown.removeAttr("style").addClass("select2-offscreen").insertAfter(this.selection).show())},focus:function(){this.close();this.selection.focus()},isFocused:function(){return this.selection[0]===document.activeElement},cancel:function(){this.parent.cancel.apply(this,arguments);this.selection.focus()}, +initContainer:function(){var a,b=this.dropdown;this.selection=a=this.container.find(".select2-choice");this.search.bind("keydown",this.bind(function(a){if(this.enabled)if(a.which===f.PAGE_UP||a.which===f.PAGE_DOWN)l(a);else if(this.opened())switch(a.which){case f.UP:case f.DOWN:this.moveHighlight(a.which===f.UP?-1:1);l(a);break;case f.TAB:case f.ENTER:this.selectHighlighted();l(a);break;case f.ESC:this.cancel(a),l(a)}else a.which===f.TAB||f.isControl(a)||f.isFunctionKey(a)||a.which===f.ESC||!1=== +this.opts.openOnEnter&&a.which===f.ENTER||this.open()}));this.search.bind("focus",this.bind(function(){this.selection.attr("tabIndex","-1")}));this.search.bind("blur",this.bind(function(){this.opened()||this.container.removeClass("select2-container-active");window.setTimeout(this.bind(function(){this.selection.attr("tabIndex",this.opts.element.attr("tabIndex"))}),10)}));a.bind("mousedown",this.bind(function(){this.opened()?(this.close(),this.selection.focus()):this.enabled&&this.open()}));b.bind("mousedown", +this.bind(function(){this.search.focus()}));a.bind("focus",this.bind(function(){this.container.addClass("select2-container-active");this.search.attr("tabIndex","-1")}));a.bind("blur",this.bind(function(){this.opened()||this.container.removeClass("select2-container-active");window.setTimeout(this.bind(function(){this.search.attr("tabIndex",this.opts.element.attr("tabIndex"))}),10)}));a.bind("keydown",this.bind(function(a){if(this.enabled)if(a.which===f.PAGE_UP||a.which===f.PAGE_DOWN)l(a);else if(!(a.which=== +f.TAB||f.isControl(a)||f.isFunctionKey(a)||a.which===f.ESC)&&!(!1===this.opts.openOnEnter&&a.which===f.ENTER))if(a.which==f.DELETE)this.opts.allowClear&&this.clear();else{this.open();if(a.which!==f.ENTER&&!(48>a.which)){var b=String.fromCharCode(a.which).toLowerCase();a.shiftKey&&(b=b.toUpperCase());this.search.focus();this.search.val(b)}l(a)}}));a.delegate("abbr","mousedown",this.bind(function(a){this.enabled&&(this.clear(),l(a),this.close(),this.triggerChange(),this.selection.focus())}));this.setPlaceholder(); +this.search.bind("focus",this.bind(function(){this.container.addClass("select2-container-active")}))},clear:function(){this.opts.element.val("");this.selection.find("span").empty();this.selection.removeData("select2-data");this.setPlaceholder()},initSelection:function(){if(""===this.opts.element.val())this.close(),this.setPlaceholder();else{var a=this;this.opts.initSelection.call(null,this.opts.element,function(b){b!==g&&null!==b&&(a.updateSelection(b),a.close(),a.setPlaceholder())})}},prepareOpts:function(){var a= +this.parent.prepareOpts.apply(this,arguments);"select"===a.element.get(0).tagName.toLowerCase()&&(a.initSelection=function(a,c){var d=a.find(":selected");e.isFunction(c)&&c({id:d.attr("value"),text:d.text()})});return a},setPlaceholder:function(){var a=this.getPlaceholder();""===this.opts.element.val()&&a!==g&&!(this.select&&""!==this.select.find("option:first").text())&&(this.selection.find("span").html(this.opts.escapeMarkup(a)),this.selection.addClass("select2-default"),this.selection.find("abbr").hide())}, +postprocessResults:function(a,b){var c=0,d=this,f=!0;this.results.find(".select2-result-selectable").each2(function(a,b){if(m(d.id(b.data("select2-data")),d.opts.element.val()))return c=a,!1});this.highlight(c);!0===b&&(f=this.showSearchInput=F(a.results)>=this.opts.minimumResultsForSearch,this.dropdown.find(".select2-search")[f?"removeClass":"addClass"]("select2-search-hidden"),e(this.dropdown,this.container)[f?"addClass":"removeClass"]("select2-with-searchbox"))},onSelect:function(a){var b=this.opts.element.val(); +this.opts.element.val(this.id(a));this.updateSelection(a);this.close();this.selection.focus();m(b,this.id(a))||this.triggerChange()},updateSelection:function(a){var b=this.selection.find("span");this.selection.data("select2-data",a);b.empty();a=this.opts.formatSelection(a,b);a!==g&&b.append(this.opts.escapeMarkup(a));this.selection.removeClass("select2-default");this.opts.allowClear&&this.getPlaceholder()!==g&&this.selection.find("abbr").show()},val:function(){var a,b=null,c=this;if(0===arguments.length)return this.opts.element.val(); +a=arguments[0];if(this.select)this.select.val(a).find(":selected").each2(function(a,c){b={id:c.attr("value"),text:c.text()};return!1}),this.updateSelection(b),this.setPlaceholder();else{if(this.opts.initSelection===g)throw Error("cannot call val() if initSelection() is not defined");a?(this.opts.element.val(a),this.opts.initSelection(this.opts.element,function(a){c.opts.element.val(!a?"":c.id(a));c.updateSelection(a);c.setPlaceholder()})):this.clear()}},clearSearch:function(){this.search.val("")}, +data:function(a){var b;if(0===arguments.length)return b=this.selection.data("select2-data"),b==g&&(b=null),b;!a||""===a?this.clear():(this.opts.element.val(!a?"":this.id(a)),this.updateSelection(a))}});z=x(w,{createContainer:function(){return e("<div></div>",{"class":"select2-container select2-container-multi"}).html(" <ul class='select2-choices'> <li class='select2-search-field'> <input type='text' autocomplete='off' class='select2-input'> </li></ul><div class='select2-drop select2-drop-multi' style='display:none;'> <ul class='select2-results'> </ul></div>")}, +prepareOpts:function(){var a=this.parent.prepareOpts.apply(this,arguments);"select"===a.element.get(0).tagName.toLowerCase()&&(a.initSelection=function(a,c){var d=[];a.find(":selected").each2(function(a,b){d.push({id:b.attr("value"),text:b.text()})});e.isFunction(c)&&c(d)});return a},initContainer:function(){var a;this.searchContainer=this.container.find(".select2-search-field");this.selection=a=this.container.find(".select2-choices");this.search.bind("keydown",this.bind(function(b){if(this.enabled){if(b.which=== +f.BACKSPACE&&""===this.search.val()){this.close();var c;c=a.find(".select2-search-choice-focus");if(0<c.length){this.unselect(c.first());this.search.width(10);l(b);return}c=a.find(".select2-search-choice");0<c.length&&c.last().addClass("select2-search-choice-focus")}else a.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");if(this.opened())switch(b.which){case f.UP:case f.DOWN:this.moveHighlight(b.which===f.UP?-1:1);l(b);return;case f.ENTER:case f.TAB:this.selectHighlighted(); +l(b);return;case f.ESC:this.cancel(b);l(b);return}if(!(b.which===f.TAB||f.isControl(b)||f.isFunctionKey(b)||b.which===f.BACKSPACE||b.which===f.ESC)&&!(!1===this.opts.openOnEnter&&b.which===f.ENTER))this.open(),(b.which===f.PAGE_UP||b.which===f.PAGE_DOWN)&&l(b)}}));this.search.bind("keyup",this.bind(this.resizeSearch));this.search.bind("blur",this.bind(function(a){this.container.removeClass("select2-container-active");this.search.removeClass("select2-focused");this.clearSearch();a.stopImmediatePropagation()})); +this.container.delegate(".select2-choices","mousedown",this.bind(function(a){this.enabled&&!(0<e(a.target).closest(".select2-search-choice").length)&&(this.clearPlaceholder(),this.open(),this.focusSearch(),a.preventDefault())}));this.container.delegate(".select2-choices","focus",this.bind(function(){this.enabled&&(this.container.addClass("select2-container-active"),this.dropdown.addClass("select2-drop-active"),this.clearPlaceholder())}));this.clearSearch()},enable:function(){this.enabled||(this.parent.enable.apply(this, +arguments),this.search.removeAttr("disabled"))},disable:function(){this.enabled&&(this.parent.disable.apply(this,arguments),this.search.attr("disabled",!0))},initSelection:function(){""===this.opts.element.val()&&(this.updateSelection([]),this.close(),this.clearSearch());if(this.select||""!==this.opts.element.val()){var a=this;this.opts.initSelection.call(null,this.opts.element,function(b){if(b!==g&&b!==null){a.updateSelection(b);a.close();a.clearSearch()}})}},clearSearch:function(){var a=this.getPlaceholder(); +a!==g&&0===this.getVal().length&&!1===this.search.hasClass("select2-focused")?(this.search.val(a).addClass("select2-default"),this.resizeSearch()):this.search.val(" ").width(10)},clearPlaceholder:function(){this.search.hasClass("select2-default")?this.search.val("").removeClass("select2-default"):" "===this.search.val()&&this.search.val("")},opening:function(){this.parent.opening.apply(this,arguments);this.clearPlaceholder();this.resizeSearch();this.focusSearch()},close:function(){this.opened()&& +this.parent.close.apply(this,arguments)},focus:function(){this.close();this.search.focus()},isFocused:function(){return this.search.hasClass("select2-focused")},updateSelection:function(a){var b=[],c=[],d=this;e(a).each(function(){0>i(d.id(this),b)&&(b.push(d.id(this)),c.push(this))});a=c;this.selection.find(".select2-search-choice").remove();e(a).each(function(){d.addSelectedChoice(this)});d.postprocessResults()},tokenize:function(){var a=this.search.val(),a=this.opts.tokenizer(a,this.data(),this.bind(this.onSelect), +this.opts);null!=a&&a!=g&&(this.search.val(a),0<a.length&&this.open())},onSelect:function(a){this.addSelectedChoice(a);this.select&&this.postprocessResults();this.opts.closeOnSelect?(this.close(),this.search.width(10)):0<this.countSelectableResults()?(this.search.width(10),this.resizeSearch(),this.positionDropdown()):this.close();this.triggerChange({added:a});this.focusSearch()},cancel:function(){this.close();this.focusSearch()},addSelectedChoice:function(a){var b=e("<li class='select2-search-choice'> <div></div> <a href='#' onclick='return false;' class='select2-search-choice-close' tabindex='-1'></a></li>"), +c=this.id(a),d=this.getVal(),f;f=this.opts.formatSelection(a,b);b.find("div").replaceWith("<div>"+this.opts.escapeMarkup(f)+"</div>");b.find(".select2-search-choice-close").bind("mousedown",l).bind("click dblclick",this.bind(function(a){this.enabled&&(e(a.target).closest(".select2-search-choice").fadeOut("fast",this.bind(function(){this.unselect(e(a.target));this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");this.close();this.focusSearch()})).dequeue(), +l(a))})).bind("focus",this.bind(function(){this.enabled&&(this.container.addClass("select2-container-active"),this.dropdown.addClass("select2-drop-active"))}));b.data("select2-data",a);b.insertBefore(this.searchContainer);d.push(c);this.setVal(d)},unselect:function(a){var b=this.getVal(),c,d,a=a.closest(".select2-search-choice");if(0===a.length)throw"Invalid argument: "+a+". Must be .select2-search-choice";c=a.data("select2-data");d=i(this.id(c),b);0<=d&&(b.splice(d,1),this.setVal(b),this.select&& +this.postprocessResults());a.remove();this.triggerChange({removed:c})},postprocessResults:function(){var a=this.getVal(),b=this.results.find(".select2-result-selectable"),c=this.results.find(".select2-result-with-children"),d=this;b.each2(function(b,c){var e=d.id(c.data("select2-data"));0<=i(e,a)?c.addClass("select2-disabled").removeClass("select2-result-selectable"):c.removeClass("select2-disabled").addClass("select2-result-selectable")});c.each2(function(a,b){0==b.find(".select2-result-selectable").length? +b.addClass("select2-disabled"):b.removeClass("select2-disabled")});b.each2(function(a,b){if(!b.hasClass("select2-disabled")&&b.hasClass("select2-result-selectable"))return d.highlight(0),!1})},resizeSearch:function(){var a,b,c,d,f=this.search.outerWidth()-this.search.width();a=this.search;q||(c=a[0].currentStyle||window.getComputedStyle(a[0],null),q=e("<div></div>").css({position:"absolute",left:"-10000px",top:"-10000px",display:"none",fontSize:c.fontSize,fontFamily:c.fontFamily,fontStyle:c.fontStyle, +fontWeight:c.fontWeight,letterSpacing:c.letterSpacing,textTransform:c.textTransform,whiteSpace:"nowrap"}),e("body").append(q));q.text(a.val());a=q.width()+10;b=this.search.offset().left;c=this.selection.width();d=this.selection.offset().left;b=c-(b-d)-f;b<a&&(b=c-f);40>b&&(b=c-f);this.search.width(b)},getVal:function(){var a;if(this.select)return a=this.select.val(),null===a?[]:a;a=this.opts.element.val();return s(a,this.opts.separator)},setVal:function(a){var b;this.select?this.select.val(a):(b= +[],e(a).each(function(){0>i(this,b)&&b.push(this)}),this.opts.element.val(0===b.length?"":b.join(this.opts.separator)))},val:function(){var a,b=[],c=this;if(0===arguments.length)return this.getVal();if(a=arguments[0])if(this.setVal(a),this.select)this.select.find(":selected").each(function(){b.push({id:e(this).attr("value"),text:e(this).text()})}),this.updateSelection(b);else{if(this.opts.initSelection===g)throw Error("val() cannot be called if initSelection() is not defined");this.opts.initSelection(this.opts.element, +function(a){var b=e(a).map(c.id);c.setVal(b);c.updateSelection(a);c.clearSearch()})}else this.opts.element.val(""),this.updateSelection([]);this.clearSearch()},onSortStart:function(){if(this.select)throw Error("Sorting of elements is not supported when attached to <select>. Attach to <input type='hidden'/> instead.");this.search.width(0);this.searchContainer.hide()},onSortEnd:function(){var a=[],b=this;this.searchContainer.show();this.searchContainer.appendTo(this.searchContainer.parent());this.resizeSearch(); +this.selection.find(".select2-search-choice").each(function(){a.push(b.opts.id(e(this).data("select2-data")))});this.setVal(a);this.triggerChange()},data:function(a){var b=this,c;if(0===arguments.length)return this.selection.find(".select2-search-choice").map(function(){return e(this).data("select2-data")}).get();a||(a=[]);c=e.map(a,function(a){return b.opts.id(a)});this.setVal(c);this.updateSelection(a);this.clearSearch()}});e.fn.select2=function(){var a=Array.prototype.slice.call(arguments,0),b, +c,d,f,h="val destroy opened open close focus isFocused container onSortStart onSortEnd enable disable positionDropdown data".split(" ");this.each(function(){if(0===a.length||"object"===typeof a[0])b=0===a.length?{}:e.extend({},a[0]),b.element=e(this),"select"===b.element.get(0).tagName.toLowerCase()?f=b.element.attr("multiple"):(f=b.multiple||!1,"tags"in b&&(b.multiple=f=!0)),c=f?new z:new y,c.init(b);else if("string"===typeof a[0]){if(0>i(a[0],h))throw"Unknown method: "+a[0];d=g;c=e(this).data("select2"); +if(c!==g&&(d="container"===a[0]?c.container:c[a[0]].apply(c,a.slice(1)),d!==g))return!1}else throw"Invalid arguments to select2 plugin: "+a;});return d===g?this:d};e.fn.select2.defaults={width:"copy",closeOnSelect:!0,openOnEnter:!0,containerCss:{},dropdownCss:{},containerCssClass:"",dropdownCssClass:"",formatResult:function(a,b,c){b=[];B(a.text,c.term,b);return b.join("")},formatSelection:function(a){return a?a.text:g},formatResultCssClass:function(){return g},formatNoMatches:function(){return"No matches found"}, +formatInputTooShort:function(a,b){return"Please enter "+(b-a.length)+" more characters"},formatSelectionTooBig:function(a){return"You can only select "+a+" item"+(1==a?"":"s")},formatLoadMore:function(){return"Loading more results..."},formatSearching:function(){return"Searching..."},minimumResultsForSearch:0,minimumInputLength:0,maximumSelectionSize:0,id:function(a){return a.id},matcher:function(a,b){return 0<=b.toUpperCase().indexOf(a.toUpperCase())},separator:",",tokenSeparators:[],tokenizer:H, +escapeMarkup:function(a){return a&&"string"===typeof a?a.replace(/&/g,"&"):a},blurOnChange:!1};window.Select2={query:{ajax:C,local:D,tags:E},util:{debounce:A,markMatch:B},"class":{"abstract":w,single:y,multi:z}}}})(jQuery); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/docs.html b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/docs.html new file mode 100644 index 000000000..c02950247 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/docs.html @@ -0,0 +1,38 @@ +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the License is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + ~ KIND, either express or implied. See the License for the + ~ specific language governing permissions and limitations + ~ under the License. +--> + +<script id="rest_docs" type="text/html"> + <div id="rest-doc-header"> + <div class="page-header"> + <h3><b>${$.i18n.prop('docs.rest.header')}</b></h3> + </div> + <div id="docs_rest_choice"> + <ul> + <li><a class="cursor-hand" onclick="displayArchivaRestDocs();">Archiva Rest Api Docs</a></li> + <li><a class="cursor-hand" onclick="displayArchivaRestUIDocs();">Archiva Rest Api UI Docs</a></li> + <li><a class="cursor-hand" onclick="displayRedbackRestDocs();">Redback Rest Api UI Docs</a></li> + </ul> + </div> + </div> + <div id="rest_docs_content"> + </div> +</script> + +<script id="users_docs" type="text/html"> +</script>
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/general-admin.html b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/general-admin.html new file mode 100644 index 000000000..d7eb7bef2 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/general-admin.html @@ -0,0 +1,1100 @@ +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the License is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + ~ KIND, either express or implied. See the License for the + ~ specific language governing permissions and limitations + ~ under the License. +--> +<script id="legacy-artifact-path-main" type="text/html"> + <div id="legacy-artifact-path-screen"> + <div class="page-header"> + <h2>${$.i18n.prop('legacy-artifact-paths.list')}</h2> + </div> + + <ul id="legacy-artifact-paths-view-tabs" class="nav nav-tabs"> + <li id="legacy-artifact-paths-view-tabs-li-grid"> + <a data-toggle="tab" href="#legacy-artifact-paths-view" id="legacy-artifact-paths-view-tabs-a-grid">${$.i18n.prop('legacy-artifact-paths.grid.tab.title')}</a> + </li> + <li id="legacy-artifact-paths-view-tabs-li-edit"> + <a data-toggle="tab" href="#legacy-artifact-paths-edit">${$.i18n.prop('add')}</a> + </li> + </ul> + <div id="legacy-artifact-paths-view-tabs-content" class="tab-content"> + <div id="legacy-artifact-paths-view" class="tab-pane"> + <table class="table table-striped table-bordered" id="legacy-artifact-paths-table" + data-bind="simpleGrid: gridViewModel,simpleGridTemplate:'ko-legacy-artifact-paths-grid',pageLinksId:'legacy-artifact-pathsPagination'"> + </table> + <div id="legacy-artifact-pathsPagination"></div> + </div> + <div id="legacy-artifact-paths-edit" class="tab-pane" data-bind='template: {name:"legacy-artifact-paths-edit-tmpl"}'></div> + </div> + </div> +</script> + +<script id='ko-legacy-artifact-paths-grid' type='text/html'> + <thead> + <tr> + {{each(i, columnDefinition) columns}} + <th>${ columnDefinition.headerText }</th> + {{/each}} + <th>${$.i18n.prop('delete')}</th> + </tr> + </thead> + <tbody> + {{each(i, row) itemsOnCurrentPage()}} + <tr data-bind="css:{ 'modified': row.modified()}"> + {{each(j, columnDefinition) columns}} + {{var val = (typeof columnDefinition.rowText == 'function' ? columnDefinition.rowText(row) : row[columnDefinition.rowText])}} + <td> + ${val} + </td> + {{/each}} + <td> + <a href="#" data-bind="click: function(){ removeLegacyArtifactPath(row) }"> + <span class="btn btn-danger"> + <i class="icon-trash icon-white"/> + </span> + </a> + </td> + </tr> + {{/each}} + </tbody> + +</script> + +<script id="legacy-artifact-paths-edit-tmpl" type="text/html"> + <form id="legacy-artifact-paths-edit-form" class="well form-horizontal"> + <fieldset id="legacy-artifact-paths-edit-fieldset"> + <div class="control-group"> + <label class="control-label" for="groupId">${$.i18n.prop('legacy-artifact-paths.groupId')}</label> + <div class="controls"> + <input type="text" class="xlarge required" id="groupId" name="groupId" size="8" + data-bind="value: legacyArtifactPath.groupId"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="artifactId">${$.i18n.prop('legacy-artifact-paths.artifactId')}</label> + <div class="controls"> + <input type="text" class="xlarge required" id="artifactId" name="artifactId" size="8" + data-bind="value: legacyArtifactPath.artifactId"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="version">${$.i18n.prop('legacy-artifact-paths.version')}</label> + <div class="controls"> + <input type="text" class="xlarge required" id="version" name="version" size="8" + data-bind="value: legacyArtifactPath.version"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="classifier">${$.i18n.prop('legacy-artifact-paths.classifier')}</label> + <div class="controls"> + <input type="text" class="xlarge" id="classifier" name="classifier" size="8" + data-bind="value: legacyArtifactPath.classifier"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="type">${$.i18n.prop('legacy-artifact-paths.type')}</label> + <div class="controls"> + <input type="text" class="xlarge required" id="type" name="type" size="8" + data-bind="value: legacyArtifactPath.type"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="path">${$.i18n.prop('legacy-artifact-paths.path')}</label> + <div class="controls"> + <input type="text" class="xlarge required" id="path" name="path" size="8" + data-bind="value: legacyArtifactPath.path"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="artifact">${$.i18n.prop('legacy-artifact-paths.artifact')}</label> + <div class="controls"> + <span title="calculated from values" class="uneditable-input" + id="artifact" data-bind="text: legacyArtifactPath.artifact"></span> + </div> + </div> + + </fieldset> + <button id="network-proxy-btn-save" data-bind="click: save" class="btn">${$.i18n.prop('save')}</button> + <button id="network-proxy-btn-cancel" data-bind="click: displayGrid" class="btn">${$.i18n.prop('cancel')}</button> + <button id="network-proxy-btn-calculate-path" data-bind="click: calculatePath" class="btn btn-success">${$.i18n.prop('legacy-artifact-paths.calculatePath')}</button> + </form> +</script> + +<script id="legacy-artifact-path-delete-warning-tmpl" type="text/html"> + <div> + <span class="label label-warning">${$.i18n.prop('warning.not.undone.operation')}</span> + </div> +</script> + +<script id="repository-scanning-main" type="text/html"> + <div id="repository-scanning-screen"> + <div class="page-header"> + <h2>${$.i18n.prop('repository-scanning.head')}</h2> + </div> + </div> + + <ul id="repositories-tabs" class="nav nav-tabs"> + <li class="active"> + <a data-toggle="tab" href="#file-types-content">${$.i18n.prop('repository-scanning.file-types.head')}</a> + </li> + <li> + <a data-toggle="tab" href="#consumers-content">${$.i18n.prop('repository-scanning.consumers.head')}</a> + </li> + </ul> + + <div class="tab-content"> + <div id="file-types-content" class="tab-pane active" data-bind='template: {name:"file-types-tmpl"}'> + </div> + <div id="consumers-content" class="tab-pane"> + <div id="consumers-known-content" data-bind='template: {name:"consumers-known-content-tmpl"}'></div> + <div id="consumers-invalid-content" data-bind='template: {name:"consumers-invalid-content-tmpl"}'></div> + </div> + </div> + +</script> + +<script id="file-types-tmpl" type="text/html"> +<div class="accordion" id="accordion-file-types"> + <div class="span4"> + {{each(i, fileType) fileTypes}} + <div class="accordion-group"> + <div class="accordion-heading"> + <a class="accordion-toggle" href="#collapse-pattern-${fileType.id}" + data-parent="#accordion-file-types" data-toggle="collapse">${fileType.id} <i class="icon-resize-vertical"/></a> + </div> + <div id="collapse-pattern-${fileType.id}" class="accordion-body collapse"> + <table class="table table-condensed"> + {{each(j,pattern) fileType.patterns}} + <tr> + <td>${pattern}</td> + <td> + <a href="#" data-bind="click: function(){ removeFileTypePattern(fileType.id(),pattern) }"> + <span class="btn btn-danger"> + <i class="icon-trash icon-white"/> + </span> + </a> + </td> + </tr> + {{/each}} + <tr> + <td><input type="text" id="pattern-${fileType.id}"/></td> + <td> + <a href="#" data-bind="click: function(){addFileTypePattern(fileType.id())}"> + <span class="btn btn-success"> + <i class="icon-plus-sign icon-white"/> + </span> + </a> + </td> + </tr> + </table> + </div> + </div> + {{/each}} + </div> +</div> +</script> + +<script id="consumers-known-content-tmpl" type="text/html"> + <div class="page-header"> + <h4>${$.i18n.prop('repository-scanning.consumers.know-content.head')}</h4> + </div> + <table class="table table-condensed"> + <thead> + <tr> + <th>${$.i18n.prop('repository-scanning.consumers.grid.enabled')}</th> + <th>${$.i18n.prop('repository-scanning.consumers.grid.id')}</th> + <th>${$.i18n.prop('repository-scanning.consumers.grid.description')}</th> + </tr> + </thead> + <tbody> + {{each(i,knownAdminRepositoryConsumer) knownAdminRepositoryConsumers}} + <tr> + {{if knownAdminRepositoryConsumer.enabled()==true}} + <td> + <a class="cursor-hand" data-bind="click: function(){ disableKnowContentConsumer(knownAdminRepositoryConsumer) }"> + <img src="images/weather-clear-22-22.png"/> + </a> + </td> + {{else}} + <td> + <a class="cursor-hand" data-bind="click: function(){ enableKnowContentConsumer(knownAdminRepositoryConsumer) }"> + <img src="images/dialog-error-22-22.png"/> + </a> + </td> + {{/if}} + + <td>${knownAdminRepositoryConsumer.id}</td> + <td>${knownAdminRepositoryConsumer.description}</td> + </tr> + {{/each}} + </tbody> + </table> +</script> + +<script id="consumers-invalid-content-tmpl" type="text/html"> + <div class="page-header"> + <h4>${$.i18n.prop('repository-scanning.consumers.invalid-content.head')}</h4> + </div> + <table class="table table-condensed"> + <thead> + <tr> + <th>${$.i18n.prop('repository-scanning.consumers.grid.enabled')}</th> + <th>${$.i18n.prop('repository-scanning.consumers.grid.id')}</th> + <th>${$.i18n.prop('repository-scanning.consumers.grid.description')}</th> + </tr> + </thead> + <tbody> + {{each(i,invalidAdminRepositoryConsumer) invalidAdminRepositoryConsumers}} + <tr> + {{if invalidAdminRepositoryConsumer.enabled()==true}} + <td> + <a href="#" data-bind="click: function(){ disableInvalidContentConsumer(invalidAdminRepositoryConsumer) }"> + <img src="images/weather-clear-22-22.png"/> + </a> + </td> + {{else}} + <td> + <a href="#" data-bind="click: function(){ enableInvalidContentConsumer(invalidAdminRepositoryConsumer) }"> + <img src="images/dialog-error-22-22.png"/> + </a> + </td> + {{/if}} + <td>${invalidAdminRepositoryConsumer.id}</td> + <td>${invalidAdminRepositoryConsumer.description}</td> + </tr> + {{/each}} + </tbody> + </table> +</script> + +<script id="network-configuration-screen" type="text/html"> + <div class="page-header"> + <h4>${$.i18n.prop('network-configuration.header')}</h4> + </div> + <div id="network-configuration-form" data-bind='template: {name:"network-configuration-form-tmpl"}'></div> +</script> + +<script id="network-configuration-form-tmpl" type="text/html"> + <form id="network-configuration-edit-form" class="well form-horizontal"> + <fieldset id="network-configuration-edit-fieldset"> + <div class="control-group"> + <label class="control-label" for="maxTotal">${$.i18n.prop('network-configuration.maxTotal')}</label> + <div class="controls"> + <input type="text" class="xlarge required digits" id="maxTotal" name="maxTotal" size="8" + data-bind="value: networkConfiguration().maxTotal"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="maxTotal">${$.i18n.prop('network-configuration.maxTotalPerHost')}</label> + <div class="controls"> + <input type="text" class="xlarge required digits" id="maxTotalPerHost" name="maxTotalPerHost" size="8" + data-bind="value: networkConfiguration().maxTotalPerHost"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="usePooling">${$.i18n.prop('network-configuration.usePooling')}</label> + <div class="controls"> + <input type="checkbox" id="usePooling" name="usePooling" data-bind="checked: networkConfiguration().usePooling"/> + </div> + </div> + </fieldset> + <button id="network-configuration-btn-save" data-loading-text="${$.i18n.prop('common.loading')}" + data-bind="click: save" class="btn">${$.i18n.prop('save')}</button> + </form> +</script> + +<script id="ui-configuration-screen" type="text/html"> + <div class="page-header"> + <h4>${$.i18n.prop('ui-configuration.header')}</h4> + </div> + <div id="ui-configuration-form" data-bind='template: {name:"ui-configuration-form-tmpl"}'></div> +</script> + +<script id="ui-configuration-form-tmpl" type="text/html"> + <form id="ui-configuration-edit-form" class="well form-horizontal"> + <fieldset id="ui-configuration-edit-fieldset"> + <div class="control-group"> + <label class="control-label" for="maxTotal">${$.i18n.prop('ui-configuration.applicationUrl')}</label> + <div class="controls"> + <input type="text" class="input-xxlarge required digits" id="applicationUrl" name="applicationUrl" size="8" + data-bind="value: uiConfiguration().applicationUrl"/> + </div> + </div> + + <div class="control-group"> + <label class="control-label" for="disableRegistration">${$.i18n.prop('ui-configuration.disableRegistration')}</label> + <div class="controls"> + <input type="checkbox" id="disableRegistration" name="disableRegistration" data-bind="checked: uiConfiguration().disableRegistration"/> + </div> + </div> + + </fieldset> + <button id="ui-configuration-btn-save" data-bind="click: save" class="btn" data-loading-text="${$.i18n.prop('common.loading')}">${$.i18n.prop('save')}</button> + </form> +</script> + +<script id="system-status-main" type="text/html"> + <div class="page-header"> + <h4>${$.i18n.prop('system-status.header.version.info')}</h4> + </div> + <div id="status_version_info"> + <img src="images/small-spinner.gif"/> + </div> + <div class="page-header"> + <h3>${$.i18n.prop('system-status.header.main')} <a class="cursor-hand" onclick="refreshSystemStatus()"><img src="images/view-refresh-22-22.png"/></a></h3> + </div> + <div class="page-header"> + <h4>${$.i18n.prop('system-status.header.queues')} <a class="cursor-hand" onclick="displayQueueEntries()"><img src="images/view-refresh.png"/></a></h4> + </div> + <div id="status_queues"> + <img src="images/small-spinner.gif"/> + </div> + + <div class="page-header"> + <h4>${$.i18n.prop('system-status.header.scanning')} <a class="cursor-hand" onclick="displayScanningStats()"><img src="images/view-refresh.png"/></a></h4> + </div> + <div id="status_scanning"> + <img src="images/small-spinner.gif"/> + </div> + + <div class="page-header"> + <h4>${$.i18n.prop('system-status.header.caches')} <a class="cursor-hand" onclick="displayCacheEntries()"><img src="images/view-refresh.png"/></a></h4> + </div> + <div id="status_caches"> + <img src="images/small-spinner.gif"/> + </div> + + <div class="page-header"> + <h4>${$.i18n.prop('system-status.header.memory')} <a class="cursor-hand" onclick="displayMemoryUsage()"><img src="images/view-refresh.png"/></a></h4> + </div> + <div id="status_memory_info"> + <img src="images/small-spinner.gif"/> + </div> + + <div class="page-header"> + <h4>${$.i18n.prop('system-status.header.current.time')}</h4> + </div> + <div id="status_current_time"> + <img src="images/small-spinner.gif"/> + </div> + +</script> + +<script id="status_caches_tmpl" type="text/html"> + <a class="btn btn-warning" onclick="flushAllCaches()"> + ${$.i18n.prop('system-status.caches.flushAll')} + </a> + <table class="table table-condensed"> + <thead> + <tr> + <th>${$.i18n.prop('system-status.caches.grid.header.key')}</th> + <th>${$.i18n.prop('system-status.caches.grid.header.size')}</th> + <th>${$.i18n.prop('system-status.caches.grid.header.cacheHits')}</th> + <th>${$.i18n.prop('system-status.caches.grid.header.cacheMiss')}</th> + <th>${$.i18n.prop('system-status.caches.grid.header.cacheHitRate')}</th> + <th>${$.i18n.prop('system-status.caches.grid.header.inMemorySize')}</th> + <th>${$.i18n.prop('system-status.caches.grid.header.flush')}</th> + </tr> + </thead> + <tbody> + {{each(i,cacheEntry) cacheEntries}} + <tr> + <td>${cacheEntry.key}</td> + <td>${cacheEntry.size}</td> + <td>${cacheEntry.cacheHits}</td> + <td>${cacheEntry.cacheMiss}</td> + <td>${cacheEntry.cacheHitRate}</td> + <td>${cacheEntry.inMemorySize}</td> + <td> + <a onclick="flushCache('${cacheEntry.key}')"> + {{if cacheEntry.size > 0 }} + <img src="images/user-trash-full.png"/> + {{else}} + <img src="images/user-trash.png"/> + {{/if}} + </a> + </td> + </tr> + {{/each}} + </tbody> + </table> +</script> + + +<script id="status_queues_tmpl" type="text/html"> + <table class="table table-condensed"> + <thead> + <tr> + <th>${$.i18n.prop('system-status.queues.grid.header.key')}</th> + <th>${$.i18n.prop('system-status.queues.grid.header.size')}</th> + </tr> + </thead> + <tbody> + {{each(i,queueEntry) queueEntries}} + <tr> + <td>${queueEntry.key}</td> + <td>${queueEntry.entriesNumber}</td> + </tr> + {{/each}} + </tbody> + </table> +</script> + +<script id="status_scanning_tmpl" type="text/html"> + {{if repositoryScannerStatisticsList.length == 0}} + <h5>No scans in progress.</h5> + {{else}} + <table class="table table-condensed"> + <thead> + <tr> + <th>${$.i18n.prop('system-status.scanning.grid.header.repository')}</th> + <th>${$.i18n.prop('system-status.scanning.grid.header.files.processed')}</th> + <th>${$.i18n.prop('system-status.scanning.grid.header.files.new')}</th> + <th>${$.i18n.prop('system-status.scanning.grid.header.stats')}</th> + </tr> + </thead> + <tbody> + {{each(i,repositoryScannerStatistics) repositoryScannerStatisticsList}} + <tr> + <td>${repositoryScannerStatistics.managedRepository.name()}</td> + <td>${repositoryScannerStatistics.totalFileCount}</td> + <td>${repositoryScannerStatistics.newFileCount}</td> + <td> + <blockquote> + <table> + <thead> + <tr> + <th>${$.i18n.prop('system-status.scanning.consumers.grid.header.name')}</th> + <th>${$.i18n.prop('system-status.scanning.consumers.grid.header.total')}</th> + <th>${$.i18n.prop('system-status.scanning.consumers.grid.header.average')} ms</th> + <th>${$.i18n.prop('system-status.scanning.consumers.grid.header.invocations.time')}</th> + </tr> + </thead> + <tbody> + {{each(j,consumerScanningStatistics) repositoryScannerStatistics.consumerScanningStatisticsList}} + <tr> + <td>${consumerScanningStatistics.consumerKey}</td> + <td>${consumerScanningStatistics.count}</td> + <td>${consumerScanningStatistics.average}ms</td> + <td>${consumerScanningStatistics.time}ms</td> + </tr> + {{/each}} + </tbody> + </table> + </blockquote> + </td> + </tr> + {{/each}} + </tbody> + </table> + {{/if}} +</script> + +<script id="changeAppearance" type="text/html"> + <div class="page-header"> + <h2>${$.i18n.prop('appearance-configuration.title-page')}</h2> + </div> + + <h2>${$.i18n.prop('appearance-configuration.organisation-details')}</h2> + + <p> + ${$.i18n.prop('apperance-configuration.details-description')} + </p> + + <form id="appearance-configuration-form-id" class="well form-horizontal"> + <fieldset id="appearance-configuration-fielset-id"> + <div class="control-group"> + <label class="control-label" for="name">${$.i18n.prop('appearance-configuration.name-label')}</label> + <div class="controls"> + <input type="text" class="input-xlarge required" id="name" name="name" size="50" + data-bind="value: organisationInformation().name"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="name">${$.i18n.prop('appearance-configuration.url-label')}</label> + <div class="controls"> + <input type="text" class="input-xlarge required" id="url" name="url" size="50" + data-bind="value: organisationInformation().url"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" + for="name">${$.i18n.prop('appearance-configuration.logoLocation-label')}</label> + <div class="controls"> + <input type="text" class="input-xxlarge" id="logoLocation" name="logoLocation" size="50" + data-bind="value: organisationInformation().logoLocation"/> + </div> + </div> + </fieldset> + <button id="appearance-configuration-btn-save" data-loading-text="${$.i18n.prop('common.loading')}" data-bind="click: save" class="btn">${$.i18n.prop('save')}</button> + </form> +</script> + + +<script id="file-upload-screen" type="text/html"> + <div id="file-upload-main" data-bind='template:{name:"file-upload-tmpl"}'></div> +</script> + +<script id="file-upload-tmpl" type="text/html"> + <div class="page-header"> + <h3>${$.i18n.prop('fileupload.header')}</h3> + </div> + <form id="fileupload" action="restServices/archivaUiServices/fileUploadService" method="POST" + enctype="multipart/form-data" class="well form-horizontal"> + + <fieldset id="network-proxy-edit-fieldset"> + <div class="control-group"> + <label class="control-label" for="repositoryId">${$.i18n.prop('fileupload.repositoryId')}</label> + <div class="controls"> + <select id="repositoryId" + data-bind="options: managedRepositories, optionsText: 'name',optionsValue:'id', + value: repositoryId"></select> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="groupId">${$.i18n.prop('fileupload.groupId')}</label> + <div class="controls"> + <input type="text" class="xlarge required" data-bind="value: groupId" id="groupId" name="groupId" size="10" /> + </div> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="artifactId">${$.i18n.prop('fileupload.artifactId')}</label> + <div class="controls"> + <input type="text" class="xlarge required" data-bind="value: artifactId" id="artifactId" name="artifactId" size="10" /> + </div> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="version">${$.i18n.prop('fileupload.version')}</label> + <div class="controls"> + <input type="text" class="xlarge required" data-bind="value: version" id="version" name="version" size="10" /> + </div> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="packaging">${$.i18n.prop('fileupload.packaging')}</label> + <div class="controls"> + <input type="text" class="xlarge required" data-bind="value: packaging" id="packaging" name="packaging" size="10" /> + </div> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="generatePom">${$.i18n.prop('fileupload.generatePom')}</label> + <div class="controls"> + <input type="checkbox" class="xlarge" data-bind="value: generatePom" id="generatePom" name="generatePom" /> + </div> + </div> + </div> + </fieldset> + + <div class="row-fluid fileupload-buttonbar"> + <div class="span7"> + <span class="btn btn-success fileinput-button"> + <i class="icon-plus icon-white"></i> + <span>${$.i18n.prop('fileupload.file.choose')}</span> + <input type="file" name="files[]" multiple=""> + </span> + <button type="submit" class="btn btn-primary start"> + <i class="icon-upload icon-white"></i> + <span>${$.i18n.prop('fileupload.start')}</span> + </button> + <button type="reset" class="btn btn-warning cancel"> + <i class="icon-ban-circle icon-white"></i> + <span>${$.i18n.prop('fileupload.cancel')}</span> + </button> + <button type="button" class="btn btn-danger delete"> + <i class="icon-trash icon-white"></i> + <span>${$.i18n.prop('fileupload.delete')}</span> + </button> + <input type="checkbox" class="toggle"> + </div> + <div class="span5"> + <div class="progress progress-success progress-striped active"> + <div class="bar" style="width:0%;"></div> + </div> + </div> + </div> + <div> + <a href="#" id="fileupload-save-files"> + <span class="btn btn-info" data-bind='click: saveArtifacts'> + <i class="icon-file icon-white"></i> + <span>${$.i18n.prop('fileupload.save')}</span> + </span> + </a> + </div> + <div class="fileupload-loading"></div> + <br> + <table class="table table-striped"> + <tbody class="files" data-toggle="modal-gallery" data-target="#modal-gallery" id="uploaded-files-list"></tbody> + </table> +</form> + +</script> + + +<script id="template-upload" type="text/html"> + {% for (var i=0, file; file=o.files[i]; i++) { %} + <tr class="template-upload"> + <td class="name"><span>{%=file.name%}</span></td> + <td><input type="text" id="classifier" name="classifier" placeholder="classifier" value=""/></td> + <td><span>pomFile:</span><input type="checkbox" id="pomFile" name="pomFile"/></td> + <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td> + {% if (file.error) { %} + <td class="error" colspan="2"> + <span class="label label-important">{%=$.i18n.prop('fileupload.error')%}</span> + {%=$.i18n.prop('fileupload.errors.'+[file.error]) || file.error%} + </td> + {% } else if (o.files.valid && !i) { %} + <td> + <div class="progress progress-success progress-striped active"> + <div class="bar" style="width:0%;"></div> + </div> + </td> + <td class="start"> + {% if (!o.options.autoUpload) { %} + <button class="btn btn-primary"> + <i class="icon-upload icon-white"></i> + <span>{%=$.i18n.prop('fileupload.start')%}</span> + </button> + {% } %} + </td> + {% } else { %} + <td colspan="2"></td> + {% } %} + <td class="cancel"> + {% if (!i) { %} + <button class="btn btn-warning"> + <i class="icon-ban-circle icon-white"></i> + <span>{%=$.i18n.prop('fileupload.cancel')%}</span> + </button> + {% } %} + </td> + </tr> + {% } %} +</script> + +<script id="template-download" type="text/html"> + {% for (var i=0, file; file=o.files[i]; i++) { %} + <tr class="template-download"> + <td class="name"><span>{%=file.name%}</span></td> + <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td> + {% if (file.error) { %} + <td class="error" colspan="2"> + <span class="label label-important">{%=$.i18n.prop('fileupload.error')%}</span> + {%=$.i18n.prop('fileupload.errors.'+[file.error]) || file.error%} + </td> + {% } else { %} + <td colspan="2"></td> + {% } %} + <td class="delete"> + <button class="btn btn-danger" data-type="{%=file.deleteType%}" + data-url="restServices/archivaUiServices/fileUploadService/{%=file.deleteUrl%}"> + <i class="icon-trash icon-white"></i> + <span>{%=$.i18n.prop('fileupload.destroy')%}</span> + </button> + <input type="checkbox" name="delete" value="1"> + </td> + </tr> +{% } %} +</script> + +<script id="report-base" type="text/html"> + <div class="page-header"> + <h2>${$.i18n.prop('report.title')}</h2> + </div> + + <ul class="nav nav-tabs"> + <li class="active" id="report-stat-tab-li"><a href="#report-stat-tab-content" data-toggle="tab">${$.i18n.prop('report.statistics.title')}</a></li> + <li id="report-health-tab-li"><a href="#report-health-tab-content" data-toggle="tab">${$.i18n.prop('report.health.title')}</a></li> + <li id="report-result-tab-li" class="hide"><a href="#report-result" data-toggle="tab">${$.i18n.prop('report.result.title')}</a></li> + </ul> + + <div class="tab-content"> + <div class="tab-pane active" id="report-stat-tab-content"> + <form class="form-horizontal" id="report-statistics-form-id"> + <fieldset id="form-statistics-report"> + <div class="row-fluid"> + <div class="span6 row-fluid"> + <div class="row-fluid" id="repositoriesErrorMessage"></div> + <div class="row-fluid"> + <div class="span6 dotted"> + <h5>${$.i18n.prop('report.statistics.selected-repositories.label')}</h5> + <hr/> + <div style="min-height: 40px" + data-bind="sortable: { template: 'statistics-repositories-order-tmpl', data:statisticsReport().repositories}"> + </div> + </div> + <div class="span6 dotted"> + <h5>${$.i18n.prop('repository.groups.available-repositories.label')}</h5> + <hr/> + <div style="min-height: 40px" + data-bind="sortable: {template: 'statistics-repositories-order-tmpl',data:availableRepositories}"> + </div> + </div> + </div> + </div> + <div class="span6 well"> + <div class="control-group"> + <label for="rowCountStatistics" class="control-label"> + ${$.i18n.prop('report.statistics.row-count.label')} + </label> + <div class="controls"> + <input type="text" id="rowCountStatistics" name="rowCountStatistics" class="input-small" + data-bind="value: statisticsReport().rowCount"/> + + <a class="btn btn-warning btn-mini" id="rowcount-info-button" + data-original-title="${$.i18n.prop('report.statistics.rowCount.explanations-title')}" + data-content="${$.i18n.prop('report.statistics.rowCount.explanations')}" + data-placement="left" data-toggle="button"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + <div class="control-group"> + <label for="startDate" class="control-label"> + ${$.i18n.prop('report.statistics.start-date.label')} + </label> + <div class="controls"> + <input type="text" id="startDate" name="startDate" class="input-small" + data-bind="value: statisticsReport().startDate"/> + </div> + </div> + <div class="control-group"> + <label for="endDate" class="control-label"> + ${$.i18n.prop('report.statistics.end-date.label')} + </label> + <div class="controls"> + <input type="text" id="endDate" name="endDate" class="input-small" + data-bind="value: statisticsReport().endDate"/> + </div> + </div> + </div> + </div> + <div class="form-actions"> + <button class="btn btn-primary" data-bind="click: showStatistics"> + ${$.i18n.prop('report.statistics.btn-view')} + </button> + </div> + </fieldset> + </form> + </div> + + <div class="tab-pane" id="report-health-tab-content"> + <form class="form-horizontal" id="report-health-form-id"> + <fieldset id="form-health-report"> + <div class="control-group"> + <label for="rowCountHealth" class="control-label"> + ${$.i18n.prop('report.statistics.row-count.label')} + </label> + <div class="controls"> + <input type="text" id="rowCountHealth" name="rowCountHealth" class="input-small required" + data-bind="value: healthReport().rowCount"/> + </div> + </div> + <div class="control-group"> + <label for="groupId" class="control-label"> + ${$.i18n.prop('report.health.groupId.label')} + </label> + <div class="controls"> + <input type="text" id="groupId" name="groupId" data-bind="value: healthReport().groupId"/> + </div> + </div> + <div class="control-group"> + <label for="repositoryId" class="control-label"> + ${$.i18n.prop('report.health.repositoryId.label')} + </label> + <div class="controls"> + <select id="repositoryId" name="repositoryId" data-bind="value: healthReport().repositoryId" + class="required"> + <option value="all">${$.i18n.prop('report.select.all-repositories')}</option> + {{each(i, repoId) repositoriesList}} + <option value="${repoId}">${repoId}</option> + {{/each}} + </select> + </div> + </div> + <div class="form-actions"> + <a href="#" class="btn btn-primary" data-bind="click: showHealth"> + ${$.i18n.prop('report.health.btn-view')} + </a> + </div> + </fieldset> + </form> + </div> + + <div class="tab-pane" id="report-result"> + </div> + </div> +</script> + +<script id="statistics-repositories-order-tmpl" type="text/html"> + <div class="well draggable-item"> + ${$data} + </div> +</script> + +<script id="report-health" type="text/html"> + <div class="page-header"> + <h3>${$.i18n.prop('report.health.title')}</h3> + </div> + <table class="table table-bordered table-striped" + data-bind="simpleGrid: tableReportViewModel,simpleGridTemplate:'table-report-tmpl',pageLinksId:'reportHealthPageLinkId'"> + </table> + <div id="reportHealthPageLinkId"></div> +</script> + +<script id="report-statistics" type="text/html"> + <div class="page-header"> + <h3>${$.i18n.prop('report.statistics.title')}</h3> + </div> + <table class="table table-bordered table-striped" + data-bind="simpleGrid: tableReportViewModel,simpleGridTemplate:'table-report-tmpl',pageLinksId:'reportStatisticsPageLinkId'"> + </table> + <div id="reportStatisticsPageLinkId"></div> +</script> +<script id="table-report-tmpl" type="text/html"> + <thead> + {{each(i, columnDefinition) columns}} + <th>${ columnDefinition.headerText }</th> + {{/each}} + </thead> + <tbody> + {{each(i, row) itemsOnCurrentPage()}} + <tr> + {{each(i, columnDefinition) columns}} + {{var val = (typeof columnDefinition.rowText == 'function' ? columnDefinition.rowText(row) : row[columnDefinition.rowText])}} + <td> + ${val} + </td> + {{/each}} + </tr> + {{/each}} + </tbody> +</script> + +<script type="text/html" id="redback-runtime-configuration-main"> + <div class="page-header"> + <h2>${$.i18n.prop('redback-runtime-configuration.title')}</h2> + </div> + <div id="redback-runtime-configuration-content" data-bind='template: {name:"redback-runtime-configuration-content-tmpl"}'> + </div> +</script> + +<script type="text/html" id="redback-runtime-configuration-content-tmpl"> + <ul class="nav nav-tabs"> + <li class="active" id="redback-runtime-general-li"><a href="#redback-runtime-general-content" data-toggle="tab">${$.i18n.prop('redback.runtime.general.title')}</a></li> + <li id="redback-runtime-ldap-li"><a href="#redback-runtime-ldap-content" data-toggle="tab">${$.i18n.prop('redback.runtime.ldap.title')}</a></li> + <li id="redback-runtime-properties-li"><a href="#redback-runtime-properties-content" data-toggle="tab">${$.i18n.prop('redback.runtime.properties.title')}</a></li> + <li id="redback-runtime-users-cache-li"><a href="#redback-runtime-users-cache-content" data-toggle="tab">${$.i18n.prop('redback.runtime.users.cache.title')}</a></li> + </ul> + + <div class="tab-content"> + <div class="tab-pane active" id="redback-runtime-general-content"> + <div class="well"> + <div class="row-fluid"> + <div class="span4 dotted"> + <h5>${$.i18n.prop('redback.runtime.user-managers.impls.choosed')}</h5> + <div style="min-height: 40px" id="user-mananagers-sortables-choosed" + data-bind="sortable: { template: 'redback-runtime-general-content-usermanagers', data:usedUserManagerImpls,afterMove: userManagerImplMoved}"> + </div> + </div> + + <div class="span4 dotted"> + <h5>${$.i18n.prop('redback.runtime.user-managers.impls.available')}</h5> + <div style="min-height: 40px"id="user-mananagers-sortables-availables" + data-bind="sortable: {template: 'redback-runtime-general-content-usermanagers',data:availableUserManagerImpls,afterMove: userManagerImplMoved}"> + </div> + </div> + </div> + </div> + </div> + + <div class="tab-pane" id="redback-runtime-ldap-content"> + <div class="well"> + <form class="form-horizontal" id="redback-runtime-ldap-form-id"> + + <div class="control-group"> + <label for="ldapHost" class="control-label"> + ${$.i18n.prop('redback.runtime.ldap.host.label')} + </label> + <div class="controls"> + <input type="text" id="ldapHost" name="ldapHost" class="input-xlarge" + data-bind="value: redbackRuntimeConfiguration().ldapConfiguration().hostName"/> + </div> + </div> + <div class="control-group"> + <label for="ldapPort" class="control-label"> + ${$.i18n.prop('redback.runtime.ldap.port.label')} + </label> + <div class="controls"> + <input type="text" id="ldapPort" name="ldapPort" class="input-large" + data-bind="value: redbackRuntimeConfiguration().ldapConfiguration().port"/> + </div> + </div> + <div class="control-group"> + <label for="ldapBaseDn" class="control-label"> + ${$.i18n.prop('redback.runtime.ldap.baseDn.label')} + </label> + <div class="controls"> + <input type="text" id="ldapBaseDn" name="ldapBaseDn" class="input-xxlarge" + data-bind="value: redbackRuntimeConfiguration().ldapConfiguration().baseDn"/> + </div> + </div> + <div class="control-group"> + <label for="ldapBindDn" class="control-label"> + ${$.i18n.prop('redback.runtime.ldap.bindDn.label')} + </label> + <div class="controls"> + <input type="text" id="ldapBindDn" name="ldapBindDn" class="input-xxlarge" + data-bind="value: redbackRuntimeConfiguration().ldapConfiguration().bindDn"/> + </div> + </div> + <div class="control-group"> + <label for="ldap-ssl" class="control-label"> + ${$.i18n.prop('redback.runtime.ldap.ssl.label')} + </label> + <div class="controls"> + <input type="checkbox" id="ldap-ssl" name="ldap-ssl" + data-bind="checked: redbackRuntimeConfiguration().ldapConfiguration().ssl"/> + </div> + </div> + <div class="control-group"> + <label for="ldapPassword" class="control-label"> + ${$.i18n.prop('redback.runtime.ldap.password.label')} + </label> + <div class="controls"> + <input type="password" id="ldapPassword" name="ldapPassword" class="input-xlarge" + data-bind="value: redbackRuntimeConfiguration().ldapConfiguration().password"/> + </div> + </div> + <div class="control-group"> + <label for="ldap-context-factory" class="control-label"> + ${$.i18n.prop('redback.runtime.ldap.contextFactory.label')} + </label> + <div class="controls"> + <input type="text" id="ldap-context-factory" name="ldap-context-factory" class="input-xlarge" + data-bind="value: redbackRuntimeConfiguration().ldapConfiguration().contextFactory"/> + </div> + </div> + <div class="control-group"> + <label for="ldap-authenticationMethod" class="control-label"> + ${$.i18n.prop('redback.runtime.ldap.authenticationMethod.label')} + </label> + <div class="controls"> + <input type="text" id="ldap-authenticationMethod" name="ldap-authenticationMethod" class="input-xlarge" + data-bind="value: redbackRuntimeConfiguration().ldapConfiguration().authenticationMethod"/> + </div> + </div> + <!-- TODO extraPropertiesEntries --> + + </form> + + <button data-bind="click: checkChangedLdapConfiguration,css:{ 'btn-warning': redbackRuntimeConfiguration().ldapConfiguration().modified() }, + enabled: redbackRuntimeConfiguration().ldapConfiguration().modified()" + id="ldap-configuration-check-modification"class="btn">${$.i18n.prop('redback.runtime.ldap.checkModification')}</button> + + <button data-bind="click: checkLdapServerConfiguration" + id="ldap-configuration-check-server"class="btn">${$.i18n.prop('redback.runtime.ldap.checkServer')}</button> + + </div> + </div> + + <div class="tab-pane" id="redback-runtime-properties-content"> + + <div class="well"> + <table id="proxyConnectorsTable" + data-bind="simpleGrid: gridViewModel,simpleGridTemplate:'properties-grid',pageLinksId:'properties-grid-pagination'"> + </table> + <div id="properties-grid-pagination"></div> + </div> + </div> + + <div class="tab-pane" id="redback-runtime-users-cache-content"> + + <div class="well"> + + + <form class="form-horizontal" id="redback-runtime-general-form-id"> + <div class="control-group"> + <label for="redback-runtime-useUsersCache" class="control-label">${$.i18n.prop('redback.runtime.useUsersCache.label')}</label> + <div class="controls"> + <input type="checkbox" id="redback-runtime-useUsersCache" name="redback-runtime-useUsersCache" + data-bind="checked: redbackRuntimeConfiguration().useUsersCache"/> + </div> + </div> + + <div class="control-group"> + <label class="control-label" for="usersCacheTimeToLiveSeconds">${$.i18n.prop('redback.runtime.usersCacheTimeToLiveSeconds.label')}</label> + <div class="controls"> + <input type="text" class="xlarge required numeric" data-bind="value: redbackRuntimeConfiguration().usersCacheConfiguration().timeToLiveSeconds" + id="usersCacheTimeToLiveSeconds" name="usersCacheTimeToLiveSeconds" /> + </div> + </div> + + <div class="control-group"> + <label class="control-label" for="usersCacheTimeToIdleSeconds">${$.i18n.prop('redback.runtime.usersCacheTimeToIdleSeconds.label')}</label> + <div class="controls"> + <input type="text" class="xlarge required numeric" data-bind="value: redbackRuntimeConfiguration().usersCacheConfiguration().timeToIdleSeconds" + id="usersCacheTimeToIdleSeconds" name="usersCacheTimeToIdleSeconds" /> + </div> + </div> + + </form> + + + </div> + </div> + + <div> + <button data-bind="click: saveRedbackRuntimeConfiguration,css:{ 'btn-warning': redbackRuntimeConfiguration().modified() | redbackRuntimeConfiguration().ldapConfiguration().modified() }" + id="redback-runtime-configuration-save"class="btn">${$.i18n.prop('save')}</button> + </div> + +</script> + +<script id='properties-grid' type='text/html'> + <thead> + <tr> + <th></th> + <th>${$.i18n.prop('redback.runtime.properties.key.label')}</th> + <th>${$.i18n.prop('redback.runtime.properties.value.label')}</th> + </tr> + </thead> + <tbody> + {{each(i, row) itemsOnCurrentPage()}} + <tr> + <td> + {{var key = row.key}} + <a class="popover-doc" + data-original-title="${$.i18n.prop('redback.runtime.properties.help.title')}" + data-content="${$.i18n.prop(key+'.help.content')}"> + <span class="btn btn-info"><i class="icon-question-sign icon-white"></i></span> + </a> + </td> + <td>${row.key}</td> + <td><input type="text" class="input-xxlarge" data-bind="value: row.value"></td> + </tr> + {{/each}} + </tbody> + +</script> + +<script id="redback-runtime-general-content-usermanagers" type="text/html"> + <div class="well draggable-item"> + ${$data.description} + </div> +</script> diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/generics.html b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/generics.html new file mode 100644 index 000000000..9fd3989c8 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/generics.html @@ -0,0 +1,67 @@ +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the License is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + ~ KIND, either express or implied. See the License for the + ~ specific language governing permissions and limitations + ~ under the License. +--> +<script id='alert-message-success' type='text/html'> + <div class="alert fade in alert-success" data-alert="alert"> + <a class="close" data-dismiss="alert" href="#" id='alert-message-success-close-a'>×</a> + ${message} + </div> +</script> +<script id='alert-message-error' type='text/html'> + <div class="alert fade in alert-error" data-alert="alert"> + <a class="close" data-dismiss="alert" href="#" id='alert-message-error-close-a'>×</a> + ${message} + </div> +</script> +<script id='alert-message-warning' type='text/html'> + <div class="alert fade in alert-heading" data-alert="alert"> + <a class="close" data-dismiss="alert" href="#" id='alert-message-warning-close-a'>×</a> + ${message} + </div> +</script> +<script id='alert-message-info' type='text/html'> + <div class="alert fade in alert-info" data-alert="alert"> + <a class="close" data-dismiss="alert" href="#" id='alert-message-info-close-a'>×</a> + ${message} + </div> +</script> + +<script id='footer-tmpl' type='text/html'> + <div class="pull-left"> + <a target="_blank" href="http://archiva.apache.org/">Apache Archiva - ${version}</a> + </div> + <div class="pull-right"> + Copyright © ${copyrightRange} <a target="_blank" href="http://www.apache.org/">The Apache Software + Foundation</a> + </div> +</script> + +<script id="ko_simpleGrid_pageLinks" type="text/html"> + <div class="pagination"> + <ul> + {{each(i) ko.utils.range(1, maxPageIndex)}} + <li data-bind="css: { active: i == currentPageIndex() }"> + <a href="#" data-bind="click: function() { currentPageIndex(i) }"> + ${ i + 1 } + </a> + </li> + {{/each}} + </ul> + </div> +</script> + diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/menu.html b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/menu.html new file mode 100644 index 000000000..4be060d2f --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/menu.html @@ -0,0 +1,116 @@ +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the License is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + ~ KIND, either express or implied. See the License for the + ~ specific language governing permissions and limitations + ~ under the License. +--> +<script type="text/html" id="main_menu_tmpl"> + <div id="main-menu"> + + <ul class="nav nav-list" data-bind="foreach: artifactMenuItems"> + <!-- ko ifnot: id --> + <li class="nav-header archiva-nav-header" data-bind="text: text"></li> + <!-- /ko --> + <!-- ko if: id --> + <li data-bind='redbackP: $data.redback, css: { active: $data.href == "#"+$root.activeMenuId() }'> + <a data-bind="text: text, attr: { id: id, href: href}"></a> + </li> + <!-- /ko --> + </ul> + + <ul class="nav nav-list" redback-permissions="{permissions: ['archiva-manage-configuration']}" + data-bind="foreach: administrationMenuItems"> + <!-- ko ifnot: id --> + <li class="nav-header archiva-nav-header" data-bind="text: text"></li> + <!-- /ko --> + <!-- ko if: id --> + <li data-bind='redbackP: $data.redback, css: { active: $data.href == "#"+$root.activeMenuId() }'> + <a data-bind="text: text, attr: { id: id, href: href}"></a> + </li> + <!-- /ko --> + </ul> + + <ul class="nav nav-list" redback-permissions="{permissions: ['archiva-manage-users']}" + data-bind="foreach: usersMenuItems"> + <!-- ko ifnot: id --> + <li class="nav-header archiva-nav-header" data-bind="text: text"></li> + <!-- /ko --> + <!-- ko if: id --> + <li data-bind='redbackP: $data.redback, css: { active: $data.href == "#"+$root.activeMenuId() }'> + <a data-bind="text: text, attr: { id: id, href: href}"></a> + </li> + <!-- /ko --> + </ul> + + <ul class="nav nav-list" data-bind="foreach: docsMenuItems"> + <!-- ko ifnot: id --> + <li class="nav-header archiva-nav-header" data-bind="text: text"></li> + <!-- /ko --> + <!-- ko if: id --> + <li data-bind='redbackP: $data.redback, css: { active: $data.href == "#"+$root.activeMenuId() }'> + <a data-bind="text: text, attr: { id: id, href: href, target: target}"></a> + </li> + <!-- /ko --> + </ul> + + </div> +</script> + +<script id="topbar_menu_tmpl" type="text/html"> + <div id="topbar-menu"> + <div class="navbar navbar-fixed-top"><!-- navbar-inverse for black topbar olamy: prefer non black :-) --> + + <div style="max-height: 40px" class="navbar-inner"> + <div class="container-fluid"> + <div id="organisation-logo" style="max-height: 40px" class="pull-left"></div> + <ul class="nav pull-right"> + <li id="create-admin-link" style="display: none"> + <a href="#open-admin-create-box" onclick="adminCreateBox();" id="create-admin-link-a"> + <span class="label label-important">${$.i18n.prop('create.admin.page.link')}</span> + </a> + </li> + <li id="login-link" style="display: none"> + <a onclick="loginBox();" id="login-link-a"> + <span class="btn btn-success label force-upper-case">${$.i18n.prop('login')}</span> + </a> + </li> + <li id="change-password-link"> + <a onclick="editUserDetailsBox();"> + <span class="btn btn-warning label force-upper-case">${$.i18n.prop('edit.details')}</span> + </a> + </li> + <li id="logout-link" style="display: none"> + <a onclick="logout(false);" id="logout-link-a"> + <span class="btn btn-danger label force-upper-case">${$.i18n.prop('logout')}</span> + </a> + </li> + <li id="register-link" style="display: none"> + <a onclick="registerBox();" id="register-link-a"> + <span class="btn btn-info label force-upper-case">${$.i18n.prop('register')}</span> + </a> + </li> + <li> + <div class="ui-widget navbar-search"> + <input type="text" class="ui-autocomplete-input search-query" id="quick-search-autocomplete" + placeholder="${$.i18n.prop('menu.topbar.quicksearch')}"/> + </div> + </li> + </ul> + </div> + </div> + + </div> + </div> +</script>
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/modal.html b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/modal.html new file mode 100644 index 000000000..3ec4278ca --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/modal.html @@ -0,0 +1,42 @@ +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the License is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + ~ KIND, either express or implied. See the License for the + ~ specific language governing permissions and limitations + ~ under the License. +--> +<div id="dialog-confirm-modal" class="modal hide fade" style="display: block;"> + <div class="modal-header"> + <a class="close" href="#" data-dismiss="modal">×</a> + + <h3 id="dialog-confirm-modal-header-title"></h3> + </div> + <div class="modal-body"> + <p id="dialog-confirm-modal-body-text"></p> + </div> + <div class="modal-footer"> + <a class="btn btn-secondary" id="dialog-confirm-modal-cancel" data-loading-text="${$.i18n.prop('common.loading')}">${$.i18n.prop('cancel')}</a> + <a class="btn btn-primary" id="dialog-confirm-modal-ok" data-loading-text="${$.i18n.prop('common.loading')}">${$.i18n.prop('ok')}</a> + </div> +</div> + +<div id="dialog-modal-merge-repo" class="modal hide fade" style="display: block;"> + <div class="modal-header"> + <a class="close" href="#" data-dismiss="modal">×</a> + + <h3 id="dialog-modal-merge-repo-header-title">${$.i18n.prop('managedrepository.repomerge.dialog.header')}</h3> + </div> + <div class="modal-body" id="dialog-modal-merge-repo-body-text">> + </div> +</div> diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/repositories.html b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/repositories.html new file mode 100644 index 000000000..335a5afc4 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/repositories.html @@ -0,0 +1,1686 @@ +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the License is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + ~ KIND, either express or implied. See the License for the + ~ specific language governing permissions and limitations + ~ under the License. +--> +<script id="repositoriesMain" type="text/html"> + <div class="page-header"> + <h2><img src="images/system-file-manager-32-32.png"/>${$.i18n.prop('administration.repositories')}</h2> + </div> + + <ul id="repositories-tabs" class="nav nav-tabs"> + <li class="active"> + <a data-toggle="tab" href="#managed-repositories-content">${$.i18n.prop('managedrepositories.grid.head')}</a> + </li> + <li> + <a data-toggle="tab" href="#remote-repositories-content">${$.i18n.prop('remoterepositories.grid.head')}</a> + </li> + </ul> + <div class="tab-content"> + <div id="managed-repositories-content" class="tab-pane active"> + <ul id="managed-repositories-pills" class="nav nav-pills"> + <li class="active" id="managed-repositories-view-li"> + <a data-toggle="tab" href="#managed-repositories-view" id="managed-repositories-view-a">${$.i18n.prop('managedrepositories.grid.tab.title')}</a> + </li> + <li id="managed-repository-edit-li"> + <a data-toggle="tab" href="#managed-repository-edit">${$.i18n.prop('add')}</a> + </li> + </ul> + <div id="managed-repositories-tabs-content" class="pill-content"> + <div id="managed-repositories-view" class="pill-pane active"> + <div id="managed-repositories-bulk-save-btn" + data-bind='template:{name:"managed-repositories-bulk-save-tmpl"}'></div> + <table class="table table-striped table-bordered" id="managed-repositories-table" + data-bind="simpleGrid: gridViewModel,simpleGridTemplate:'ko_managed-repositoriesGrid',pageLinksId:'managed-repositoriesPagination',data:'managedRepositories'"> + </table> + <div id="managed-repositoriesPagination"></div> + <div id="managed-repositories-pom-snippet"></div> + </div> + <div id="managed-repository-edit" class="pill-pane" data-bind='template: {name:"managed-repository-edit-tmpl"}'> + </div> + </div> + </div> + + + <div id="remote-repositories-content" class="tab-pane"> + <ul id="remote-repositories-pills" class="nav nav-pills"> + <li class="active" id="remote-repositories-view-li"> + <a data-toggle="tab" href="#remote-repositories-view" id="remote-repositories-view-a">${$.i18n.prop('remoterepositories.grid.tab.title')}</a> + </li> + <li id="remote-repository-edit-li"> + <a data-toggle="tab" href="#remote-repository-edit">${$.i18n.prop('add')}</a> + </li> + </ul> + <div id="remote-repositories-tabs-content" class="pill-content"> + <div id="remote-repositories-view" class="pill-pane active"> + <div id="remote-repositories-bulk-save-btn" + data-bind='template:{name:"remote-repositories-bulk-save-tmpl"}'></div> + <table class="table table-striped table-bordered" id="remote-repositories-table" + data-bind="simpleGrid: gridViewModel,simpleGridTemplate:'ko_remote-repositoriesGrid',pageLinksId:'remote-repositoriesPagination',data:'remoteRepositories'"> + </table> + <div id="remote-repositoriesPagination"></div> + </div> + <div id="remote-repository-edit" class="pill-pane" data-bind='template:{name:"remote-repository-edit-tmpl"}'> + </div> + </div> + </div> + </div> +</script> + +<script id='ko_managed-repositoriesGrid' type='text/html'> + <thead> + <tr> + {{each(i, columnDefinition) columns}} + <th title="${ columnDefinition.title }">${ columnDefinition.headerText }</th> + {{/each}} + <th>Releases</th> + <th>Snapshots</th> + <th>${$.i18n.prop('managedrepository.actions')}</th> + <th>${$.i18n.prop('edit')}</th> + <th>${$.i18n.prop('delete')}</th> + <th>${$.i18n.prop('modified')}</th> + <th>${$.i18n.prop('managed.repository.rss.header')}</th> + <th title="${$.i18n.prop('managedrepository.stats')}">${$.i18n.prop('managedrepository.stats.grid.header')}</th> + </tr> + </thead> + <tbody> + {{each(i, row) itemsOnCurrentPage()}} + <tr data-bind="css:{ 'modified': row.modified()}"> + {{each(j, columnDefinition) columns}} + <td> + ${ typeof columnDefinition.rowText == 'function' ? columnDefinition.rowText(row) : row[columnDefinition.rowText] } + </td> + {{/each}} + <td> + {{if row.releases() == true}} + <img src="images/weather-clear-22-22.png" title="${$.i18n.prop('release.included')}"/> + {{else}} + <img src="images/dialog-error-22-22.png" title="${$.i18n.prop('release.notincluded')}"/> + {{/if}} + </td> + + <td> + {{if row.snapshots() == true}} + <img src="images/weather-clear-22-22.png" title="${$.i18n.prop('snapshots.included')}"/> + {{else}} + <img src="images/dialog-error-22-22.png" title="${$.i18n.prop('snapshots.notincluded')}"/> + {{/if}} + </td> + <td> + <div class="btn-group"> + <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">Actions<span class="caret"></span> </a> + <ul class="dropdown-menu"> + <li> + <a href="#" data-bind="click: function(){ scanNow(row) }"> + <span class="btn btn-success"> + <i class="icon-refresh icon-white"></i> + </span> + ${$.i18n.prop('managedrepository.scan.grid.header')} + </a> + </li> + <li> + <a href="#" data-bind="click: function(){directoriesScan(row)}"> + <span class="btn btn-warning"> + <i class="icon-wrench icon-white"></i> + </span> + ${$.i18n.prop('managedrepository.scan.directories.grid.header')} + </a> + </li> + <li> + <a href="#" data-bind="click: function(){ showPomSnippet(row) }"> + <span class="btn btn-info"> + <i class="icon-user icon-white"></i> + </span> + ${$.i18n.prop('managedrepository.pomsnippet')} + </a> + </li> + <li> + {{if row.stageRepoNeeded()}} + stage + {{/if}} + </li> + <li> + <!-- todo check archiva-merge-repository operation --> + <a href="#" data-bind="click: function(){ mergeRepo(row) }"> + <span class="btn btn-info"> + <i class="icon-share icon-white"></i> + </span> + ${$.i18n.prop('managedrepository.mergerepo')} + </a> + </li> + </ul> + </div> + </td> + <td> + <a href="#" data-bind="click: function(){ editManagedRepository(row) }"> + <span class="btn btn-primary"> + <i class="icon-pencil icon-white"/> + </span> + </a> + </td> + <td> + <a href="#" data-bind="click: function(){ removeManagedRepository(row) }"> + <span class="btn btn-danger"> + <i class="icon-trash icon-white"/> + </span> + </a> + </td> + {{if row.modified()}} + <td> + <a href="#" class="btn btn-warning" data-bind="click: function(){ updateManagedRepository(row) }">${$.i18n.prop('save')}</a> + </td> + {{else}} + <td></td> + {{/if}} + <td> + <a href="${row.feedsUrl}"><img src="images/atom.gif" alt="" + title="${$.i18n.prop('managedrepository.feeds')} ${row.name()}"/></a> + </td> + <td id="managedrepository-stats-${row.id()}"> + <img src="images/utilities-system-monitor-22-22.png" + data-original-title="${$.i18n.prop('managedrepository.stats')}" + data-bind="event: { mouseover: function(){ showStats(row) }, mouseout: function(){ hideStats(row) },}" + id="managedrepository-stats-img-${row.id()}"/> + </td> + </tr> + {{/each}} + </tbody> + +</script> + +<script id="managed-repository-edit-tmpl" type='text/html'> + <form id="managed-repository-edit-form" class="well form-horizontal"> + <fieldset id="managed-repository-edit-fieldset"> + <div class="control-group"> + <label class="control-label" for="id">${$.i18n.prop('id')}</label> + + <div class="controls"> + {{if update}} + <span class="uneditable-input">${$data.managedRepository.id}</span> + {{else}} + <input type="text" class="input-xlarge required" id="id" name="id" size="50" + data-bind="value: managedRepository.id,css:{'uneditable-input': update},readonly:update"/> + {{/if}} + <a class="btn btn-warning btn-mini popover-doc" id="managedRepository-id-info-button" + data-original-title="${$.i18n.prop('managedRepository.id.help.title')}" + data-content="${$.i18n.prop('managedRepository.id.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="name">${$.i18n.prop('name')}</label> + + <div class="controls"> + <input type="text" class="input-xlarge required" id="name" name="name" size="50" + data-bind="value: managedRepository.name"/> + <a class="btn btn-warning btn-mini popover-doc" id="managedRepository-name-info-button" + data-original-title="${$.i18n.prop('managedRepository.name.help.title')}" + data-content="${$.i18n.prop('managedRepository.name.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="location">${$.i18n.prop('directory')}</label> + + <div class="controls"> + <input type="text" class="input-xxlarge required" id="location" name="location" size="50" + data-bind="value: managedRepository.location"/> + <a class="btn btn-warning btn-mini popover-doc" id="managedRepository-location-info-button" + data-original-title="${$.i18n.prop('managedRepository.location.help.title')}" + data-content="${$.i18n.prop('managedRepository.location.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="indexDirectory">${$.i18n.prop('index.directory')}</label> + + <div class="controls"> + <input type="text" class="input-xxlarge" id="indexDirectory" name="indexDirectory" size="50" + data-bind="value: managedRepository.indexDirectory"/> + <a class="btn btn-warning btn-mini popover-doc" id="managedRepository-indexDirectory-info-button" + data-original-title="${$.i18n.prop('managedRepository.indexDirectory.help.title')}" + data-content="${$.i18n.prop('managedRepository.indexDirectory.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="layout">${$.i18n.prop('type')}</label> + + <div class="controls"> + <select id="layout" + data-bind="options: availableLayouts,optionsText: 'label',optionsValue:'type',value: managedRepository.layout"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="cronExpression">${$.i18n.prop('cronExpression')}</label> + + <div class="controls"> + <input type="text" id="cronExpression" class="required" name="cronExpression" size="40" + data-bind="value: managedRepository.cronExpression"/> + <a class="btn btn-warning btn-mini popover-doc" id="cronExpression-info-button" + data-original-title="${$.i18n.prop('cronExpression.help.title')}" + data-content="${$.i18n.prop('cronExpression.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="daysOlder">${$.i18n.prop('daysOlder')}</label> + + <div class="controls"> + <input type="text" id="daysOlder" class="digits" name="daysOlder" size="5" + data-bind="value: managedRepository.daysOlder"/> + <a class="btn btn-warning btn-mini popover-doc" id="managedRepository-daysOlder-info-button" + data-original-title="${$.i18n.prop('managedRepository.daysOlder.help.title')}" + data-content="${$.i18n.prop('managedRepository.daysOlder.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="retentionCount">${$.i18n.prop('retentionCount')}</label> + + <div class="controls"> + <input type="text" id="retentionCount" name="retentionCount" size="5" + data-bind="value: managedRepository.retentionCount"/> + <a class="btn btn-warning btn-mini popover-doc" id="managedRepository-retentionCount-info-button" + data-original-title="${$.i18n.prop('managedRepository.retentionCount.help.title')}" + data-content="${$.i18n.prop('managedRepository.retentionCount.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="description">${$.i18n.prop('description')}</label> + + <div class="controls"> + <textarea rows="3" id="description" name="description" + data-bind="value: managedRepository.description"></textarea> + <a class="btn btn-warning btn-mini popover-doc" id="managedRepository-description-info-button" + data-original-title="${$.i18n.prop('managedRepository.description.help.title')}" + data-content="${$.i18n.prop('managedRepository.description.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="releases">${$.i18n.prop('releases')}</label> + + <div class="controls"> + <input type="checkbox" id="releases" name="releases" size="5" + data-bind="checked: managedRepository.releases"/> + <a class="btn btn-warning btn-mini popover-doc" id="managedRepository-release-info-button" + data-original-title="${$.i18n.prop('managedRepository.release.help.title')}" + data-content="${$.i18n.prop('managedRepository.release.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="snapshots">${$.i18n.prop('snapshots')}</label> + + <div class="controls"> + <input type="checkbox" id="snapshots" name="snapshots" size="5" + data-bind="checked: managedRepository.snapshots"/> + <a class="btn btn-warning btn-mini popover-doc" id="managedRepository-snapshots-info-button" + data-original-title="${$.i18n.prop('managedRepository.snapshots.help.title')}" + data-content="${$.i18n.prop('managedRepository.snapshots.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="blockRedeployments">${$.i18n.prop('blockRedeployments')}</label> + + <div class="controls"> + <input type="checkbox" id="blockRedeployments" name="blockRedeployments" size="5" + data-bind="checked: managedRepository.blockRedeployments"/> + <a class="btn btn-warning btn-mini popover-doc" id="managedRepository-blockRedeployments-info-button" + data-original-title="${$.i18n.prop('managedRepository.blockRedeployments.help.title')}" + data-content="${$.i18n.prop('managedRepository.blockRedeployments.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="scanned">${$.i18n.prop('scanned')}</label> + + <div class="controls"> + <input type="checkbox" id="scanned" name="scanned" size="5" data-bind="checked: managedRepository.scanned"/> + <a class="btn btn-warning btn-mini popover-doc" id="managedRepository-scanned-info-button" + data-original-title="${$.i18n.prop('managedRepository.scanned.help.title')}" + data-content="${$.i18n.prop('managedRepository.scanned.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="deleteReleasedSnapshots">${$.i18n.prop('deleteReleasedSnapshots')}</label> + + <div class="controls"> + <input type="checkbox" id="deleteReleasedSnapshots" name="deleteReleasedSnapshots" size="5" + data-bind="checked: managedRepository.deleteReleasedSnapshots"/> + <a class="btn btn-warning btn-mini popover-doc" id="managedRepository-deleteReleasedSnapshots-info-button" + data-original-title="${$.i18n.prop('managedRepository.deleteReleasedSnapshots.help.title')}" + data-content="${$.i18n.prop('managedRepository.deleteReleasedSnapshots.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="stageRepoNeeded">${$.i18n.prop('stageRepoNeeded')}</label> + + <div class="controls"> + <input type="checkbox" id="stageRepoNeeded" name="stageRepoNeeded" size="5" + data-bind="checked: managedRepository.stageRepoNeeded"/> + <a class="btn btn-warning btn-mini popover-doc" id="managedRepository-stageRepoNeeded-info-button" + data-original-title="${$.i18n.prop('managedRepository.stageRepoNeeded.help.title')}" + data-content="${$.i18n.prop('managedRepository.stageRepoNeeded.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="skipPackedIndexCreation">${$.i18n.prop('skipPackedIndexCreation')}</label> + + <div class="controls"> + <input type="checkbox" id="skipPackedIndexCreation" name="skipPackedIndexCreation" size="5" + data-bind="checked: managedRepository.skipPackedIndexCreation"/> + <a class="btn btn-warning btn-mini popover-doc" id="skipPackedIndexCreation-info-button" + data-original-title="${$.i18n.prop('skipPackedIndexCreation.help.title')}" + data-content="${$.i18n.prop('skipPackedIndexCreation.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + + </fieldset> + <button data-bind="click: save" class="btn" id="managed-repository-save-button">${$.i18n.prop('save')}</button> + <button data-bind="click: displayGrid" class="btn">${$.i18n.prop('cancel')}</button> + </form> +</script> + +<script id="managed-repository-delete-warning-tmpl" type='text/html'> + <div> + <span class="label label-warning">${$.i18n.prop('warning.not.undone.operation')}</span> + + <div> + <span><strong>${$.i18n.prop('managedrepository.delete.warning.message')}</strong>.</span> + + <div>${$.i18n.prop('id')}: ${id()}</div> + <div>${$.i18n.prop('name')}: ${name()}</div> + </div> + <div> + ${$.i18n.prop('managedrepository.delete.content')}: <input type="checkbox" id="managedrepository-deletecontent"> + </div> + </div> +</script> + +<script type="text/html" id="remote-repository-delete-modal-tmpl"> + <div> + <span class="label label-warning">${$.i18n.prop('warning.not.undone.operation')}</span> + </div> +</script> + +<script id="managed-repository-location-warning-tmpl" type='text/html'> + <div> + <span class="label label-warning">${$.i18n.prop('managedrepository.location.already.exists')}</span> + + <div> + <span><strong>${$.i18n.prop('managedrepository.location.already.exists.warning.message')}</strong>.</span> + + <div>${$.i18n.prop('id')}: ${id()}</div> + <div>${$.i18n.prop('name')}: ${name()}</div> + </div> + </div> +</script> +<script id="managed-repository-scan-now-modal-tmpl" type='text/html'> + <div> + ${$.i18n.prop('managedrepository.scan.all')}: <input type="checkbox" id="managed-repository-scan-now-all"> + </div> +</script> +<script id="managed-repository-stats-tmpl" type='text/html'> + <div id="managedrepository-stats-${managedRepository.id()}-popover" style="display:none"> + <div>${$.i18n.prop('managedrepository.stats.endTime')}: ${lastScanDate()}</div> + <div>${$.i18n.prop('managedrepository.stats.duration')}: ${duration()}ms</div> + <div>${$.i18n.prop('managedrepository.stats.totalFileCount')}: ${totalFileCount()}</div> + <div>${$.i18n.prop('managedrepository.stats.newFileCount')}: ${newFileCount()}</div> + </div> +</script> +<script id="pom-snippet-tmpl" type='text/html'> + <div class="page-header"> + <h2>POM Snippet</h2></div> + </div> + <div><a onclick="$('#managed-repositories-pom-snippet').effect('blind')">${$.i18n.prop('hide')}</a></div> + <pre>${$data}</pre> +</script> + +<!-- remote part --> + +<script id='ko_remote-repositoriesGrid' type='text/html'> + <thead> + <tr> + {{each(i, columnDefinition) columns}} + <th title="${ columnDefinition.title }">${ columnDefinition.headerText }</th> + {{/each}} + <th>${$.i18n.prop('edit')}</th> + <th>${$.i18n.prop('delete')}</th> + <th>${$.i18n.prop('modified')}</th> + <th>${$.i18n.prop('description')}</th> + <th>${$.i18n.prop('remoterepository.downloadremoteindex')}</th> + </tr> + </thead> + <tbody> + {{each(i, row) itemsOnCurrentPage()}} + <tr data-bind="css:{ 'modified': row.modified()}"> + {{each(j, columnDefinition) columns}} + <td> + ${ typeof columnDefinition.rowText == 'function' ? columnDefinition.rowText(row) : row[columnDefinition.rowText] } + </td> + {{/each}} + <td> + <a href="#" data-bind="click: function(){ editRemoteRepository(row) }"> + <span class="btn btn-primary"> + <i class="icon-pencil icon-white"/> + </span> + </a> + </td> + <td> + <a href="#" data-bind="click: function(){ removeRemoteRepository(row) }"> + <span class="btn btn-danger"> + <i class="icon-trash icon-white"/> + </span> + </a> + </td> + {{if row.modified()}} + <td> + <a href="#" class="btn btn-warning" data-bind="click: function(){ updateRemoteRepository(row) }">${$.i18n.prop('save')}</a> + </td> + {{else}} + <td></td> + {{/if}} + <td> + {{if row.description()}} + <a class="btn btn-warning btn-mini popover-doc" id="remoterepo-description-help" + data-content="${row.description()}" data-title="${$.i18n.prop('description')}"> + <i class="icon-question-sign icon-white"></i> + </a> + {{/if}} + </td> + <td> + <a href="#" data-bind="click: function(){ scheduleDownloadRemoteIndex(row) }"> + <span class="btn btn-success"> + <i class="icon-refresh icon-white"/> + </span> + </a> + </td> + </tr> + {{/each}} + </tbody> + +</script> + + +<script id="remote-repository-edit-tmpl" type='text/html'> + + + <form id="remote-repository-edit-form" class="well form-horizontal"> + <fieldset id="remote-repository-edit-fieldset"> + <div class="control-group"> + <label class="control-label" for="id">${$.i18n.prop('id')}</label> + + <div class="controls"> + {{if update}} + <span class="uneditable-input">${$data.remoteRepository.id}</span> + {{else}} + <input type="text" class="input-xlarge required" id="id" name="id" size="50" + data-bind="value: remoteRepository.id,css:{'uneditable-input': update},readonly:update"/> + {{/if}} + </div> + </div> + <div class="control-group"> + <label class="control-label" for="name">${$.i18n.prop('name')}</label> + + <div class="controls"> + <input type="text" class="input-xlarge required" id="name" name="name" size="50" + data-bind="value: remoteRepository.name"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="url">${$.i18n.prop('url')}</label> + + <div class="controls"> + <input type="text" class="input-xxlarge required" id="url" name="location" size="50" + data-bind="value: remoteRepository.url"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="userName">${$.i18n.prop('username')}</label> + + <div class="controls"> + <input type="text" class="input-xlarge" id="userName" name="userName" size="50" + data-bind="value: remoteRepository.userName"/> + <a class="btn btn-warning btn-mini popover-doc" id="remoteRepository-userName-info-button" + data-original-title="${$.i18n.prop('remoteRepository.userName.help.title')}" + data-content="${$.i18n.prop('remoteRepository.userName.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="password">${$.i18n.prop('password')}</label> + <div class="controls"> + <input type="password" class="input-xlarge" id="password" name="password" size="50" + data-bind="value: remoteRepository.password"/> + <a class="btn btn-warning btn-mini popover-doc" id="remoteRepository-password-info-button" + data-original-title="${$.i18n.prop('remoteRepository.password.help.title')}" + data-content="${$.i18n.prop('remoteRepository.password.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="timeout">${$.i18n.prop('timeout')}</label> + + <div class="controls"> + <input type="text" id="timeout" class="digits" name="daysOlder" size="5" + data-bind="value: remoteRepository.timeout"/> + <a class="btn btn-warning btn-mini popover-doc" id="remoteRepository-timeout-info-button" + data-original-title="${$.i18n.prop('remoteRepository.timeout.help.title')}" + data-content="${$.i18n.prop('remoteRepository.timeout.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + + <div class="control-group"> + <label class="control-label" for="layout">${$.i18n.prop('type')}</label> + + <div class="controls"> + <select id="layout" + data-bind="options: availableLayouts,optionsText: 'label',optionsValue:'type',value: remoteRepository.layout"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="downloadRemoteIndex">${$.i18n.prop('downloadRemoteIndex')}</label> + + <div class="controls"> + <input type="checkbox" id="downloadRemoteIndex" name="downloadRemoteIndex" size="5" + data-bind="checked: remoteRepository.downloadRemoteIndex"/> + <a class="btn btn-warning btn-mini popover-doc" id="remoteRepository-downloadRemoteIndex-info-button" + data-original-title="${$.i18n.prop('remoteRepository.downloadRemoteIndex.help.title')}" + data-content="${$.i18n.prop('remoteRepository.downloadRemoteIndex.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + + <div class="control-group"> + <label class="control-label" for="remoteIndexUrl">${$.i18n.prop('remoteIndexUrl')}</label> + + <div class="controls"> + <input type="text" class="input-xxlarge" id="remoteIndexUrl" name="remoteIndexUrl" size="5" + data-bind="value: remoteRepository.remoteIndexUrl"/> + <a class="btn btn-warning btn-mini popover-doc" id="remoteRepository-remoteIndexUrl-info-button" + data-original-title="${$.i18n.prop('remoteRepository.remoteIndexUrl.help.title')}" + data-content="${$.i18n.prop('remoteRepository.remoteIndexUrl.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="cronExpression">${$.i18n.prop('cronExpression')}</label> + + <div class="controls"> + <input type="text" id="cronExpression" name="cronExpression" size="40" + data-bind="value: remoteRepository.cronExpression"/> + <a class="btn btn-warning btn-mini popover-doc" id="cronExpression-info-button" + data-original-title="${$.i18n.prop('cronExpression.help.title')}" + data-content="${$.i18n.prop('cronExpression.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="indexDirectory">${$.i18n.prop('index.directory')}</label> + + <div class="controls"> + <input type="text" class="input-xlarge" id="indexDirectory" name="indexDirectory" size="50" + data-bind="value: remoteRepository.indexDirectory"/> + <a class="btn btn-warning btn-mini popover-doc" id="remoteRepository-indexDirectory-info-button" + data-original-title="${$.i18n.prop('remoteRepository.indexDirectory.help.title')}" + data-content="${$.i18n.prop('remoteRepository.indexDirectory.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="remoteDownloadTimeout">${$.i18n.prop('remoteDownloadTimeout')}</label> + + <div class="controls"> + <input type="text" id="remoteDownloadTimeout" class="digits" name="remoteDownloadTimeout" size="5" + data-bind="value: remoteRepository.remoteDownloadTimeout"/> + <a class="btn btn-warning btn-mini popover-doc" id="remoteRepository-remoteDownloadTimeout-info-button" + data-original-title="${$.i18n.prop('remoteRepository.remoteDownloadTimeout.help.title')}" + data-content="${$.i18n.prop('remoteRepository.remoteDownloadTimeout.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + + <div class="control-group"> + <label class="control-label" + for="remoteDownloadNetworkProxyId">${$.i18n.prop('remoteDownloadNetworkProxyId')}</label> + + <div class="controls"> + <select id="remoteDownloadNetworkProxyId" + data-bind="options: networkProxies, optionsText: 'id',optionsValue:'id', value: remoteRepository.remoteDownloadNetworkProxyId, optionsCaption: 'Choose...'"></select> + <a class="btn btn-warning btn-mini popover-doc" id="remoteRepository-remoteDownloadNetworkProxyId-info-button" + data-original-title="${$.i18n.prop('remoteRepository.remoteDownloadNetworkProxyId.help.title')}" + data-content="${$.i18n.prop('remoteRepository.remoteDownloadNetworkProxyId.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + + <div class="control-group"> + <label class="control-label" + for="downloadRemoteIndexOnStartup">${$.i18n.prop('downloadRemoteIndexOnStartup')}</label> + + <div class="controls"> + <input type="checkbox" id="downloadRemoteIndexOnStartup" name="downloadRemoteIndexOnStartup" + data-bind="checked: remoteRepository.downloadRemoteIndexOnStartup"/> + <a class="btn btn-warning btn-mini popover-doc" id="remoteRepository-remoteDownloadNetworkProxyId-info-button" + data-original-title="${$.i18n.prop('remoteRepository.remoteDownloadNetworkProxyId.help.title')}" + data-content="${$.i18n.prop('remoteRepository.remoteDownloadNetworkProxyId.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + + <div class="control-group"> + <label class="control-label" for="description">${$.i18n.prop('description')}</label> + + <div class="controls"> + <textarea rows="3" id="description" name="description" + data-bind="value: remoteRepository.description"></textarea> + <a class="btn btn-warning btn-mini popover-doc" id="remoteRepository-description-info-button" + data-original-title="${$.i18n.prop('remoteRepository.description.help.title')}" + data-content="${$.i18n.prop('remoteRepository.description.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + </div> + </div> + + <div class="row-fluid"> + <div class="control-group span6"> + <h4>${$.i18n.prop('remoteRepository.extraParametersEntries')} + </h4> + <a class="btn btn-warning btn-mini popover-doc" id="remoteRepository-extraParametersEntries-info-button" + data-original-title="${$.i18n.prop('remoteRepository.extraParametersEntries.help.title')}" + data-content="${$.i18n.prop('remoteRepository.extraParametersEntries.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + <div id="extra-parameters-error"></div> + <table class="table"> + <thead> + <th>${$.i18n.prop('key')}:<input type="text" id="extraParameter-key"/></th> + <th>${$.i18n.prop('value')}:<input type="text" id="extraParameter-value"/></th> + <th><a href="#" data-bind="click: function(){ addExtraParameter() }">${$.i18n.prop('add')}</a></th> + </thead> + <tbody> + {{each(i, extraParameterEntry) remoteRepository.extraParametersEntries}} + <tr> + <td>${extraParameterEntry.key}</td> + <td>${extraParameterEntry.value}</td> + <td><a href="#" data-bind="click: function(){ deleteExtraParameter(extraParameterEntry.key)}">${$.i18n.prop('delete')}</a> + </td> + </tr> + {{/each}} + </tbody> + </table> + </div> + </div> + + <div class="row-fluid"> + <div class="control-group span6"> + <h4>${$.i18n.prop('remoteRepository.extraHeadersEntries')} + </h4> + <a class="btn btn-warning btn-mini popover-doc" id="remoteRepository-extraHeadersEntries-info-button" + data-original-title="${$.i18n.prop('remoteRepository.extraHeadersEntries.help.title')}" + data-content="${$.i18n.prop('remoteRepository.extraHeadersEntries.help.content')}"> + <i class="icon-question-sign icon-white"></i> + </a> + <div id="extra-headers-error"></div> + <table class="table"> + <thead> + <th>${$.i18n.prop('key')}:<input type="text" id="extraHeader-key"/></th> + <th>${$.i18n.prop('value')}:<input type="text" id="extraHeader-value"/></th> + <th><a href="#" data-bind="click: function(){ addExtraHeader() }">${$.i18n.prop('add')}</a></th> + </thead> + <tbody> + {{each(i, extraHeaderEntry) remoteRepository.extraHeadersEntries}} + <tr> + <td>${extraHeaderEntry.key}</td> + <td>${extraHeaderEntry.value}</td> + <td><a href="#" data-bind="click: function(){ deleteExtraHeader(extraHeaderEntry.key)}">${$.i18n.prop('delete')}</a> + </td> + </tr> + {{/each}} + </tbody> + </table> + </div> + </div> + + </fieldset> + <button data-bind="click: save" data-loading-text="${$.i18n.prop('common.loading')}" + id="remote-repository-save-button" class="btn">${$.i18n.prop('save')} + </button> + <button data-bind="click: displayGrid" class="btn">${$.i18n.prop('cancel')}</button> + </form> +</script> + +<script id="remote-repository-scan-modal-tmpl" type='text/html'> + <div> + ${$.i18n.prop('remoterepository.download.remote.now')}: <input type="checkbox" id="remoterepository-scan-now"> + </div> + <div> + ${$.i18n.prop('remoterepository.download.remote.full')}: <input type="checkbox" id="remoterepository-scan-full"> + </div> +</script> + +<script id="managed-repositories-bulk-save-tmpl" type='text/html'> + {{if bulkSave()}} + <a data-bind="click: updateModifiedManagedRepositories" class="btn btn-danger" href="#">${$.i18n.prop('save.all')}</a> + {{/if}} +</script> + +<script id="remote-repositories-bulk-save-tmpl" type='text/html'> + {{if bulkSave()}} + <a data-bind="click: updateModifiedRemoteRepositories" class="btn btn-danger" href="#">${$.i18n.prop('save.all')}</a> + {{/if}} +</script> + +<script id="networkProxiesMain" type="text/html"> + <div class="page-header"> + <h2><img src="images/internet-web-browser-32-32.png"/>${$.i18n.prop('network-proxies.list')}</h2> + </div> + + <ul id="network-proxies-view-tabs" class="nav nav-tabs"> + <li id="network-proxies-view-tabs-li-grid"> + <a data-toggle="tab" href="#network-proxies-view" id="network-proxies-view-tabs-a-network-proxies-grid">${$.i18n.prop('network-proxies.grid.tab.title')}</a> + </li> + <li id="network-proxies-view-tabs-li-edit"> + <a data-toggle="tab" href="#network-proxies-edit">${$.i18n.prop('add')}</a> + </li> + </ul> + <div id="network-proxies-view-tabs-content" class="tab-content"> + <div id="network-proxies-view" class="tab-pane"> + <div id="network-proxies-bulk-save-btn" data-bind='template:{name:"network-proxies-bulk-save-tmpl"}'></div> + <table class="table table-striped table-bordered" id="networkProxiesTable" + data-bind="simpleGrid: gridViewModel,simpleGridTemplate:'ko-network-proxies-grid',pageLinksId:'network-proxiesPagination'"> + </table> + <div id="network-proxiesPagination"></div> + </div> + <div id="network-proxies-edit" class="tab-pane" data-bind='template: {name:"network-proxy-edit-tmpl"}'></div> + </div> + +</script> + +<script id='ko-network-proxies-grid' type='text/html'> + <thead> + <tr> + {{each(i, columnDefinition) columns}} + <th>${ columnDefinition.headerText }</th> + {{/each}} + <th>${$.i18n.prop('password')}</th> + <th>${$.i18n.prop('network.proxy.useNtlm')}</th> + <th>${$.i18n.prop('edit')}</th> + <th>${$.i18n.prop('delete')}</th> + <th>${$.i18n.prop('modified')}</th> + </tr> + </thead> + <tbody> + {{each(i, row) itemsOnCurrentPage()}} + <tr data-bind="css:{ 'modified': row.modified()}"> + {{each(j, columnDefinition) columns}} + {{var val = (typeof columnDefinition.rowText == 'function' ? columnDefinition.rowText(row) : + row[columnDefinition.rowText])}} + <td> + ${val} + </td> + {{/each}} + {{if row.password()}} + <td>*****</td> + {{else}} + <td></td> + {{/if}} + <td>${row.useNtlm()}</td> + <td> + <a href="#" data-bind="click: function(){ editNetworkProxy(row) }"> + <span class="btn btn-primary"> + <i class="icon-pencil icon-white"/> + </span> + </a> + </td> + <td> + <a href="#" data-bind="click: function(){ removeNetworkProxy(row) }"> + <span class="btn btn-danger"> + <i class="icon-trash icon-white"/> + </span> + </a> + </td> + {{if row.modified()}} + <td> + <a href="#" data-bind="click: function(){ updateNetworkProxy(row) }" class="btn btn-warning">${$.i18n.prop('save')}</a> + </td> + {{else}} + <td></td> + {{/if}} + + </tr> + {{/each}} + </tbody> + +</script> + +<script id="network-proxy-edit-tmpl" type='text/html'> + <form id="network-proxy-edit-form" class="well form-horizontal"> + <fieldset id="network-proxy-edit-fieldset"> + <div class="control-group"> + <label class="control-label" for="id">${$.i18n.prop('id')}</label> + + <div class="controls"> + {{if update}} + <span class="uneditable-input">${$data.networkProxy.id}</span> + {{else}} + <input type="text" class="xlarge" id="id" name="id" size="10" + data-bind="value: networkProxy.id,css:{'uneditable-input': update},readonly:update"/> + {{/if}} + </div> + </div> + <div class="control-group"> + <label class="control-label" for="protocol">${$.i18n.prop('protocol')}</label> + + <div class="controls"> + <input type="text" class="xlarge required" id="protocol" name="protocol" size="8" + data-bind="value: networkProxy.protocol"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="host">${$.i18n.prop('host')}</label> + + <div class="controls"> + <input type="text" class="xlarge required" id="host" name="host" size="15" + data-bind="value: networkProxy.host"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="port">${$.i18n.prop('port')}</label> + + <div class="controls"> + <input type="text" class="xlarge required digits" id="port" name="port" size="6" + data-bind="value: networkProxy.port"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="username">${$.i18n.prop('username')}</label> + + <div class="controls"> + <input type="text" class="xlarge" id="username" name="username" size="50" + data-bind="value: networkProxy.username"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="password">${$.i18n.prop('password')}</label> + + <div class="controls"> + <input type="password" class="xlarge" id="password" name="password" size="50" + data-bind="value: networkProxy.password"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="useNtlm">${$.i18n.prop('network.proxy.useNtlm')}</label> + + <div class="controls"> + <input type="checkbox" id="useNtlm" name="useNtlm" data-bind="checked: networkProxy.useNtlm"/> + </div> + </div> + + </fieldset> + <button id="network-proxy-btn-save" data-bind="click: save" class="btn">${$.i18n.prop('save')}</button> + {{if networkProxy.modified()}} + ${("#network-proxy-btn-save").button('reset')} + {{/if}} + <button data-bind="click: displayGrid" class="btn">${$.i18n.prop('cancel')}</button> + </form> +</script> + +<script id="network-proxies-bulk-save-tmpl" type='text/html'> + {{if bulkSave()}} + <a data-bind="click: updateModifiedNetworkProxies" class="btn btn-danger" href="#">${$.i18n.prop('save.all')}</a> + {{/if}} +</script> +<script id="network-proxy-delete-warning-tmpl" type='text/html'> + <div> + <span class="label label-warning">${$.i18n.prop('warning.not.undone.operation')}</span> + </div> +</script> + +<script id="proxyConnectorsMain" type="text/html"> + <div class="page-header"> + <h2><img src="images/preferences-system-network-proxy-32-32.png"/>${$.i18n.prop('proxy-connectors.list')}</h2> + </div> + + <ul id="proxy-connectors-view-tabs" class="nav nav-tabs"> + <li id="proxy-connectors-view-tabs-li-grid" class="active"> + <a data-toggle="tab" href="#proxy-connectors-view" id="proxy-connectors-view-tabs-a-network-proxies-grid">${$.i18n.prop('proxy-connectors.grid.tab.title')}</a> + </li> + <li id="proxy-connectors-view-tabs-li-edit"> + <a data-toggle="tab" href="#proxy-connectors-edit" + id="proxy-connectors-view-tabs-a-edit">${$.i18n.prop('add')}</a> + </li> + <li id="proxy-connectors-view-tabs-li-edit-order"> + <a data-toggle="tab" href="#proxy-connectors-edit-order" id="proxy-connectors-view-tabs-a-edit-order">${$.i18n.prop('proxy-connectors.grid.tab.edit.order')}</a> + </li> + </ul> + <div id="proxy-connectors-view-tabs-content" class="tab-content"> + <div id="proxy-connectors-view" class="tab-pane active"> + <div id="proxy-connectors-bulk-save-btn" data-bind='template:{name:"proxy-connectors-bulk-save-tmpl"}'></div> + <table class="table table-striped table-bordered" id="proxyConnectorsTable" + data-bind="simpleGrid: gridViewModel,simpleGridTemplate:'ko-proxy-connectors-grid',pageLinksId:'proxy-connectorsPagination'"> + </table> + <div id="proxy-connectorsPagination"></div> + </div> + <div id="proxy-connectors-edit" class="tab-pane"></div> + <div id="proxy-connector-edit-order" class="tab-pane span8"> + <div id="proxy-connector-edit-order-managed-repository-div" + data-bind='template:{name:"proxy-connector-edit-order-managed-repository-tmpl"}'></div> + <div id="proxy-connector-edit-order-div" + data-bind="sortable: { template: 'proxy-connector-edit-order-tmpl', data: proxyConnectors,afterMove: proxyConnectorMoved}"> + </div> + </div> + </div> + +</script> + +<script id='ko-proxy-connectors-grid' type='text/html'> + <thead> + <tr> + <th>${$.i18n.prop('proxy-connectors.grid.managedrepo.grid.header')}</th> + <th>${$.i18n.prop('proxy-connectors.grid.remoterepo.grid.header')}</th> + <th>${$.i18n.prop('proxy-connectors.grid.remoterepo.settings.popover.title')}</th> + <th>${$.i18n.prop('edit')}</th> + <th>${$.i18n.prop('delete')}</th> + <th>${$.i18n.prop('save')}</th> + <th>${$.i18n.prop('proxy-connectors.grid.header.order')}</th> + </tr> + </thead> + <tbody> + {{each(i, row) itemsOnCurrentPage()}} + <tr data-bind="css:{ 'modified': row.modified()}"> + <td>${row.sourceRepoId()}</td> + <td>${row.targetRepoId()}</td> + <td> + <a class="btn btn-info btn-mini" + id="proxy-connectors-grid-remoterepo-settings-edit-${row.sourceRepoId()}-${row.targetRepoId()}" + data-original-title="${$.i18n.prop('proxy-connectors.grid.remoterepo.settings.popover.title')}" + data-content="${buildSettings(row)}" data-bind="click: showSettings" data-html="true"> + <i class="icon-question-sign icon-white"></i> + </a> + + </td> + <td> + <a data-bind="click: function(){ editProxyConnector(row)}" href="#"> + <span class="btn btn-primary"> + <i class="icon-pencil icon-white"/> + </span> + </a> + </td> + <td> + <a href="#" data-bind="click: function(){ deleteProxyConnector(row)}"> + <span class="btn btn-danger"> + <i class="icon-trash icon-white"/> + </span> + </a> + </td> + <td> + {{if row.modified()}} + <a href="#" class="btn btn-warning" data-bind="click: function(){ updateProxyConnector(row)}"> + ${$.i18n.prop('save')} + </a> + {{/if}} + </td> + <td> + {{if orderChangeAware(row)}} + <a href="#" data-bind="click: function(){ displayOrderEdit(row)}"> + <span class="btn btn-info"> + <i class="icon-resize-vertical icon-white"/> + ${$.i18n.prop('proxy-connectors.order.edit')} + </span> + + </a> + <span class="badge badge-info">${row.order()}</span> + {{/if}} + </td> + </tr> + {{/each}} + </tbody> + <div id="proxy-connectors-grid-remoterepo-settings-content-${val}-${targetRepoId}" style="display:none"></div> +</script> + +<script id='proxy-connectors-remote-settings-popover-tmpl' type='text/html'> + <span> + {{if proxyId}} + ${$.i18n.prop('proxy-connectors.remoterepo.settings.networkproxy')}: ${proxyConnector.proxyId} + {{else}} + ${$.i18n.prop('proxy-connectors.remoterepo.settings.networkproxy')}: ${$.i18n.prop('none')} + {{/if}} + <table class="table table-bordered"> + <thead> + <th colspan="2">${$.i18n.prop('proxy-connector.policies')}</th> + </thead> + <tbody> + {{each(i, entry) proxyConnector.policiesEntries}} + {{var name = proxyConnectorsViewModel.findPolicyInformationName(entry.key)}} + <tr> + <td>${name}</td> + <td>${entry.value}</td> + </tr> + {{/each}} + </tbody> + </table> + </span> +</script> + +<script id="proxy-connector-edit-form-tmpl" type='text/html'> + + <form id="proxy-connector-edit-form" class="well form-horizontal"> + <fieldset id="remote-repository-edit-fieldset"> + <div class="control-group"> + <label class="control-label" for="proxyId">${$.i18n.prop('proxy-connector.network-proxy.id')}</label> + + <div class="controls"> + <select id="proxyId" + data-bind="options: proxyConnectorsViewModel.networkProxies, optionsText: 'id',optionsValue:'id', + value: proxyConnector.proxyId, optionsCaption: 'direct connection'"></select> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="proxyId">${$.i18n.prop('proxy-connector.managed.repository.id')}</label> + + <div class="controls"> + <select id="sourceRepoId" + data-bind="options: proxyConnectorsViewModel.managedRepositories, optionsText: 'id',optionsValue:'id', + value: proxyConnector.sourceRepoId,attr: {disabled: isUpdate() }"></select> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="proxyId">${$.i18n.prop('proxy-connector.remote.repository.id')}</label> + + <div class="controls"> + <select id="targetRepoId" + data-bind="options: proxyConnectorsViewModel.remoteRepositories, optionsText: 'id',optionsValue:'id', + value: proxyConnector.targetRepoId,attr: {disabled: isUpdate() }"></select> + </div> + </div> + <div class="row-fluid"> + <div class="control-group span6"> + <table class="table"> + <thead> + <th colspan="2">${$.i18n.prop('proxy-connector.policies')}</th> + </thead> + <tbody data-bind="foreach: proxyConnectorsViewModel.policyInformations()"> + <tr> + <td data-bind="text: name"></td> + <td> + <select data-bind="options: getPolicyOptions(id()),value:getSelectedPolicyOption(id()), + attr: { id: 'policy-'+id() },event: { change: function(){ changePolicyOption(id())},}"> + </select> + </td> + </tr> + </tbody> + </table> + </div> + </div> + <div class="row-fluid"> + <div class="control-group span6"> + <h4>${$.i18n.prop('proxy-connector.properties')}</h4> + <table class="table"> + <thead> + <th><input type="text" id="property-key"/></th> + <th><input type="text" id="property-value"/></th> + <th><a href="#" data-bind="click: function(){ addProperty() }">${$.i18n.prop('add')}</a></th> + </thead> + <tbody data-bind="foreach: proxyConnector.propertiesEntries"> + <tr> + <td data-bind="text: key"></td> + <td data-bind="text: value"></td> + <td><a href="#" data-bind="click: function(){ $parent.deleteProperty(key)}">${$.i18n.prop('delete')}</a> + </td> + </tr> + </tbody> + </table> + </div> + </div> + <div class="row-fluid"> + <div class="control-group span6"> + <h4>${$.i18n.prop('proxy-connector.blacklist')}</h4> + <table class="table"> + <thead> + <th><input type="text" id="blacklist-value"/></th> + <th><a href="#" data-bind="click: function(){ addBlacklistPattern() }">${$.i18n.prop('add')}</a></th> + </thead> + <tbody data-bind="foreach: proxyConnector.blackListPatterns"> + <tr> + <td data-bind="text: $data"></td> + <td><a href="#" data-bind="click: function(){removeBlacklistPattern($data)}">${$.i18n.prop('delete')}</a> + </td> + </tr> + </tbody> + </table> + </div> + </div> + <div class="row-fluid"> + <div class="control-group span6"> + <h4>${$.i18n.prop('proxy-connector.whitelist')}</h4> + <table class="table"> + <thead> + <th><input type="text" id="whitelist-value"/></th> + <th><a href="#" data-bind="click: function(){ addWhitelistPattern() }">${$.i18n.prop('add')}</a></th> + </thead> + <tbody data-bind="foreach: proxyConnector.whiteListPatterns"> + <tr> + <td data-bind="text: $data"></td> + <td><a href="#" data-bind="click: function(){removeWhitelistPattern($data)}">${$.i18n.prop('delete')}</a> + </td> + </tr> + </tbody> + </table> + </div> + </div> + </fieldset> + + <button id="proxy-connector-btn-save" data-bind="click: save" data-loading-text="${$.i18n.prop('common.loading')}" + class="btn">${$.i18n.prop('save')} + </button> + {{if modified()}} + ${("#network-proxy-btn-save").button('reset')} + {{/if}} + <button data-bind="click: displayGrid" class="btn">${$.i18n.prop('cancel')}</button> + + </form> + +</script> +<script id="proxy-connectors-bulk-save-tmpl" type='text/html'> + {{if bulkSave()}} + <a data-bind="click: updateModifiedProxyConnectors" class="btn btn-danger" href="#">${$.i18n.prop('save.all')}</a> + {{/if}} +</script> + +<script id="proxy-connector-edit-order-tmpl" type='text/html'> + <div class="well draggable-item network-proxy-remote-item"> + {{var remoteRepository=$parent.findRemoteRepository(targetRepoId)}} + <div class="row-fluid"> + <div class="span1"> + <img src="images/system-software-update-32-32.png"/> + <br/> + <img src="images/utilities-system-monitor-22-22.png" + id="proxy-connectors-order-remoterepo-settings-edit-${sourceRepoId()}-${targetRepoId()}" + data-original-title="${$.i18n.prop('proxy-connectors.grid.remoterepo.settings.popover.title')}" + data-bind="event: { mouseover: function(){ displaySettings(sourceRepoId(),targetRepoId())},}"> + + <div id="proxy-connectors-order-remoterepo-settings-content-${sourceRepoId()}-${targetRepoId()}" + style="display:none"></div> + </div> + <div class="span6 pull-left"> + <blockquote> + ${targetRepoId} + <br/> + ${remoteRepository.name()} (<a href="${remoteRepository.url()}" + target="_blank">${remoteRepository.url()}</a>) + </blockquote> + </div> + <div class="span2"> + <span class="badge badge-info">${order}</span> + </div> + </div> + </div> +</script> + +<script id="proxy-connector-edit-order-managed-repository-tmpl" type="text/html"> + <div class="well row-fluid"> + <div class="span1"> + <img src="images/applications-internet-32-32.png"/> + </div> + <div class="span6"> + <blockquote> + ${managedRepository.id} + <br/> + ${managedRepository.name} + </blockquote> + </div> + <div class="span2"> + {{if proxyConnectorsViewModel.bulkSave()}} + <p> + <a data-bind="click: function(){updateModifiedProxyConnectors()}" + href="#" class="btn btn-warning">${$.i18n.prop('save.all')}</a></p> + {{/if}} + </div> + </div> +</script> + +<script id="proxy-connector-delete-warning-tmpl" type='text/html'> + <div> + <span class="label label-warning">${$.i18n.prop('warning.not.undone.operation')}</span> + </div> +</script> + +<script id="repositoryGroupsMain" type="text/html"> + <div class="page-header"> + <h2><img src="images/applications-internet-2-32-32.png"/>${$.i18n.prop('repository.groups.list')}</h2> + </div> + <ul id="repository-groups-view-tabs" class="nav nav-tabs"> + <li id="repository-groups-view-tabs-li-grid" class="active"> + <a data-toggle="tab" href="#repository-groups-view" id="repository-groups-view-tabs-a-network-proxies-grid"> + ${$.i18n.prop('repository-groups.grid.tab.title')} + </a> + </li> + <li id="repository-groups-view-tabs-li-edit"> + <a data-toggle="tab" href="#repository-groups-edit" + id="repository-groups-view-tabs-a-edit">${$.i18n.prop('add')}</a> + </li> + + </ul> + <div id="repository-groups-view-tabs-content" class="tab-content"> + <div id="repository-groups-view" class="tab-pane active"> + <div id="repository-groups-table" data-bind='template:{name:"repository-groups-table-tmpl"}'> + </div> + </div> + <div id="repository-groups-edit" class="tab-pane"> + <div class="row-fluid"> + <div class="span6 dotted"> + <div id="repository-groups-edit-div" data-bind='template:{name:"repository-group-edit-tmpl"}'></div> + <div id="repository-groups-edit-order-div" style="min-height: 80px" + data-bind="sortable: { template: 'repository-group-edit-order-tmpl-choosed',data:repositoryGroup.managedRepositories,afterMove:repositoryMoved}"> + </div> + </div> + + <div class="span6 dotted"> + <h5>${$.i18n.prop('repository.groups.available.repositories')}</h5> + <br/> + + <div id="repository-groups-edit-available-repositories" style="min-height: 80px" + data-bind="sortable: { template: 'repository-group-edit-order-tmpl-available',data:availableRepositories,afterMove:repositoryMoved}"> + + </div> + </div> + + </div> + + </div> + + </div> +</script> + +<script id="repository-group-edit-order-tmpl-choosed" type="text/html"> + <div class="well draggable-item"> + <span class="pull-right"> + <i class="icon-minus-sign cursor-hand" id="minus-${$data.id()}"/> + </span> + <blockquote> + ${$data.id()} + <br/> + ${$data.name()} + <br/> + <a href="${$data.url}" target="_blank"> + ${$data.url} + </a> + <br/> + </blockquote> + + </div> +</script> + +<script id="repository-group-edit-order-tmpl-available" type="text/html"> + <div class="well draggable-item"> + <span class="pull-right"> + <i class="icon-plus-sign cursor-hand" id="plus-${$data.id()}"/> + </span> + <blockquote> + ${$data.id()} + <br/> + ${$data.name()} + <br/> + <a href="${$data.url}" target="_blank"> + ${$data.url} + </a> + <br/> + </blockquote> + + </div> +</script> + +<script id="repository-groups-table-tmpl" type="text/html"> + <table class="table table-striped table-bordered"> + <thead> + <th>${$.i18n.prop('repository.groups.groups.grid.header')}</th> + <th>${$.i18n.prop('repository.groups.repositories.grid.header')}</th> + <th>${$.i18n.prop('edit')}</th> + <th>${$.i18n.prop('delete')}</th> + <th>${$.i18n.prop('save')}</th> + </thead> + <tbody> + {{each(i, repositoryGroup) repositoryGroups}} + <tr data-bind="css:{ 'modified': repositoryGroup.modified()}"> + <td>${repositoryGroup.id}</td> + <td> + <ul> + {{each(j,id) repositoryGroup.repositories()}} + <li>${id}</li> + {{/each}} + </ul> + </td> + <td> + <a href="#" data-bind="click: function(){editRepositoryGroup(repositoryGroup)}"> + <span class="btn btn-primary"> + <i class="icon-pencil icon-white"/> + </span> + </a> + </td> + <td> + <a href="#" data-bind="click: function(){deleteRepositoryGroup(repositoryGroup)}"> + <span class="btn btn-danger"> + <i class="icon-trash icon-white"/> + </span> + </a> + </td> + <td> + {{if repositoryGroup.modified()}} + <a href="#" class="btn btn-warning" data-bind="click: function(){saveRepositoryGroup(repositoryGroup)}"> + ${$.i18n.prop('save')} + </a> + {{/if}} + </td> + </tr> + {{/each}} + </tbody> + </table> +</script> + +<script id="repository-group-edit-tmpl" type="text/html"> + <div class="row-fluid"> + {{if update}} + <div class="dotted span8"> + <blockquote> + ${repositoryGroup.id} + <br/> + <a href="${window.archivaRuntimeInfo.baseUrl}/repository/${repositoryGroup.id()}" target="_blank"> + ${applicationUrl}/repository/${repositoryGroup.id()} + </a> + </blockquote> + </div> + {{else}} + <div class="dotted span8"> + <form id="repository-group-edit-form" class="well"> + <fieldset id="repository-group-edit-fieldset"> + <div class="control-group"> + <label class="control-label" for="id">${$.i18n.prop('id')}</label> + + <div class="controls"> + <input type="text" class="input-medium required" id="id" name="id" size="15" + data-bind="value: repositoryGroup.id,css:{'uneditable-input': update},readonly:update"/> + </div> + </div> + </fieldset> + </form> + </div> + {{/if}} + {{if repositoryGroup.modified()}} + <div class="span3"> + <a href="#" class="btn btn-warning" data-loading-text="${$.i18n.prop('common.loading')}" + id="repository-group-save" data-bind="click: function(){saveRepositoryGroup(repositoryGroup)}">${$.i18n.prop('save')}</a> + </div> + <br/> + {{/if}} + </div> +</script> + + +<script id="repository-group-delete-warning-tmpl" type='text/html'> + <div> + <span class="label label-warning">${$.i18n.prop('warning.not.undone.operation')}</span> + </div> +</script> + + +<script id="merge-repo-dialog-content" type="text/html"> + <div class="btn-group btn-group-vertical"> + {{each(i, repository) repositories}} + <button class="btn" type="button" + onclick="mergeRepositories(encodeURIComponent('${sourceRepoId}'),encodeURIComponent('${repository.id()}'))"> + ${repository.name()} + </button> + {{/each}} + </div> +</script> + +<script id="merge-repo-skip-conflicts" type="text/html"> + <div> + <ul> + {{each(i, artifact) artifacts}} + <li>${artifact.groupId}:${artifact.artifactId}:${artifact.version}</li> + {{/each}} + </ul> + </div> + <div> + <button class="btn btn-success" + onclick="doMerge(encodeURIComponent('${sourceRepository}'),encodeURIComponent('${targetRepository}'),false);" + type="button">${$.i18n.prop('managedrepository.merge.domerge')} + </button> + {{if artifacts.length > 0}} + <button class="btn btn-warning" + onclick="doMerge(encodeURIComponent('${sourceRepository}'),encodeURIComponent('${targetRepository}'),true);" + type="button">${$.i18n.prop('managedrepository.merge.domerge.skipconflicts')} + </button> + {{/if}} + </div> +</script> + + +<script id="proxyConnectorsRulesMain" type="text/html"> + <div class="page-header"> + <h2>${$.i18n.prop('proxy-connector-rules.list')}</h2> + </div> + + <ul id="proxy-connectors-rules-view-tabs" class="nav nav-tabs"> + <li id="proxy-connectors-rules-view-tabs-li-grid" class="active"> + <a data-toggle="tab" href="#proxy-connector-rules-view" id="proxy-connectors-rules-view-tabs-a-grid">${$.i18n.prop('proxy-connectors-rules.grid.tab.title')}</a> + </li> + <li id="proxy-connectors-rules-view-tabs-li-edit"> + <a data-toggle="tab" href="#proxy-connector-rules-edit" id="proxy-connectors-rules-view-tabs-a-edit">${$.i18n.prop('add')}</a> + </li> + </ul> + <div id="proxy-connectors-rules-view-tabs-content" class="tab-content"> + <div id="proxy-connector-rules-view" class="tab-pane active"> + <div id="proxy-connectors-rules-view-tabs-bulk-save-btn" + data-bind='template:{name:"proxy-connectors-rules-view-tabs-bulk-save-tmpl"}'></div> + <table class="table table-striped table-bordered" id="proxy-connectors-rules-view-tabsTable" + data-bind="simpleGrid: gridViewModel,simpleGridTemplate:'ko-proxy-connectors-rules-grid',pageLinksId:'proxy-connectors-rules-pagination'"> + </table> + <div id="proxy-connectors-rules-view-tabs-pagination"></div> + </div> + <div id="proxy-connector-rules-edit" class="tab-pane"> + <div class="row-fluid"> + <div class="span6 dotted"> + <div id="proxy-connectors-rules-edit-div" + data-bind='template:{name:"proxy-connectors-rules-edit-tmpl"}'></div> + <div id="proxy-connectors-rules-edit-order-div" style="min-height: 80px" + data-bind="sortable: { template: 'proxy-connectors-rules-edit-proxy-connectors-tmpl-choosen',data:proxyConnectorRule.proxyConnectors,afterMove:proxyConnectorMoved}"> + </div> + </div> + + <div class="span6 dotted"> + <h5>${$.i18n.prop('proxy-connector-rules.available.proxyConnectors')}</h5> + <br/> + + <div id="proxy-connectors-rules-available-proxy-connectors" style="min-height: 80px" + data-bind="sortable: { template: 'proxy-connectors-rules-edit-proxy-connectors-tmpl-availables',data:availableProxyConnectors,afterMove:proxyConnectorMoved}"> + + </div> + </div> + + </div> + </div> + + </div> + +</script> + +<script id='ko-proxy-connectors-rules-grid' type='text/html'> + <thead> + <tr> + <th title="${$.i18n.prop('proxy-connector-rules.grid.pattern.title')}"> + ${$.i18n.prop('proxy-connector-rules.grid.pattern.header')} + </th> + <th title="${$.i18n.prop('proxy-connector-rules.grid.type.title')}"> + ${$.i18n.prop('proxy-connector-rules.grid.type.header')} + </th> + <th>${$.i18n.prop('proxy-connector-rules.grid.proxy-connectors.header')}</th> + <th>${$.i18n.prop('edit')}</th> + <th>${$.i18n.prop('delete')}</th> + <th>${$.i18n.prop('save')}</th> + </tr> + </thead> + <tbody> + {{each(i, row) itemsOnCurrentPage()}} + <tr data-bind="css:{ 'modified': row.modified()}"> + <td>${row.pattern()}</td> + <td><img src="${row.ruleType.image}" title="${row.ruleType.label}"></img></td> + <td> + <ul> + {{each(j,proxyConnector) row.proxyConnectors()}} + <li>${proxyConnector.sourceRepoId()} <-> ${proxyConnector.targetRepoId()}</li> + {{/each}} + </ul> + </td> + <td> + <a href="#" data-bind="click: function(){ editProxyConnectorRule(row) }"> + <span class="btn btn-primary" data-loading-text="${$.i18n.prop('common.loading')}"> + <i class="icon-pencil icon-white"/> + </span> + </a> + </td> + <td> + <a data-bind="click: function(){ removeProxyConnectorRule(row) }" + data-loading-text="${$.i18n.prop('common.loading')}"> + <span class="btn btn-danger" data-loading-text="${$.i18n.prop('common.loading')}"> + <i class="icon-trash icon-white"/> + </span> + </a> + </td> + <td> + {{if row.modified()}} + <a href="#" id="proxy-connector-rule-update-btn" class="btn btn-warning" + data-loading-text="${$.i18n.prop('common.loading')}" + data-bind="click: function(){ updateProxyConnectorRule(row) }">${$.i18n.prop('save')}</a> + {{/if}} + </td> + </tr> + {{/each}} + </tbody> +</script> + +<script id="proxy-connectors-rules-view-tabs-bulk-save-tmpl" type="text/html"> + +</script> + +<script id="proxy-connectors-rules-edit-tmpl" type="text/html"> + <div class="row-fluid"> + {{if update}} + <div class="dotted span8"> + <blockquote> + ${proxyConnectorRule.pattern()} + <br/> + ${proxyConnectorRule.ruleType.label} + </blockquote> + </div> + {{else}} + <div class="dotted span8"> + <form id="proxy-connector-rule-edit-form" class="well"> + <fieldset id="proxy-connector-rule-edit-fieldset"> + <div class="control-group"> + <label class="control-label" for="id">${$.i18n.prop('proxy-connector-rule.pattern')}</label> + + <div class="controls"> + <input type="text" class="input-large required" id="pattern" name="pattern" size="15" + data-bind="value:proxyConnectorRule.pattern,css:{'uneditable-input': update},readonly:update"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="layout">${$.i18n.prop('type')}</label> + + <div class="controls"> + <select id="proxy-connector-rule-pattern-type" + data-bind="options: proxyConnectorRulesViewModel.ruleTypes,optionsText: 'label',optionsValue:'type',value: proxyConnectorRule.proxyConnectorRuleType"/> + </div> + </div> + </fieldset> + </form> + </div> + {{/if}} + + <div class="span3" data-bind="visible: proxyConnectorRule.modified()"> + {{if update && proxyConnectorRule.modified()}} + <a href="#" class="btn btn-warning" data-loading-text="${$.i18n.prop('common.loading')}" + id="proxy-connector-rule-update-btn" + data-bind="click: function(){updateProxyConnectorRule(proxyConnectorRule)}">${$.i18n.prop('update')}</a> + {{else}} + <a href="#" class="btn btn-warning" data-loading-text="${$.i18n.prop('common.loading')}" + id="proxy-connector-rule-add-btn" data-bind="click: function(){addProxyConnectorRule(proxyConnectorRule)}">${$.i18n.prop('add')}</a> + {{/if}} + </div> + + <br/> + + </div> +</script> + +<script id="proxy-connectors-rules-edit-proxy-connectors-tmpl-choosen" type="text/html"> + <div class="well draggable-item"> + <i class="icon-minus-sign cursor-hand pull-right" data-source-repoId="${$data.sourceRepoId()}" + data-target-repoId="${$data.targetRepoId()}"/> + <blockquote> + ${$data.sourceRepoId()} <-> ${$data.targetRepoId()} + </blockquote> + + </div> +</script> + +<script id="proxy-connectors-rules-edit-proxy-connectors-tmpl-availables" type="text/html"> + <div class="well draggable-item"> + <i class="icon-plus-sign cursor-hand pull-right" data-source-repoId="${$data.sourceRepoId()}" + data-target-repoId="${$data.targetRepoId()}"/> + <blockquote> + ${$data.sourceRepoId()} <-> ${$data.targetRepoId()} + </blockquote> + + </div> +</script>
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/search.html b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/search.html new file mode 100644 index 000000000..01a43dcbd --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/archiva/search.html @@ -0,0 +1,969 @@ +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the License is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + ~ KIND, either express or implied. See the License for the + ~ specific language governing permissions and limitations + ~ under the License. +--> + +<script id="browse-tmpl" type="text/html"> + <div> + <div class="page-header"> + <div><b>${$.i18n.prop('browse.repository')}</b></div> + <div id="selected_repository"></div> + </div> + </div> + <div id="main_browse_result"> + <div id="main_browse_result_content" class="well"> + <div id="browse_breadcrumb" data-bind='template:{name:"browse-breadcrumb-tmpl"}'></div> + <div id="browse_result" class="well" data-bind='template:{name:"browse-groups-tmpl"}'></div> + <div id="browse_artifact" class="well" data-bind='template:{name:"browse-artifact-tmpl"}'></div> + <div id="browse_artifact_detail" class="well" data-bind='template:{name:"browse-artifact-detail-tmpl"}'></div> + </div> + </div> +</script> + +<script id="browse-groups-div-tmpl" type="text/html"> + <div id="browse-groups-div" data-bind='template:{name:"browse-groups-tmpl"}'> + </div> +</script> + +<script id="browse-groups-tmpl" type="text/html"> + <div> + <ul> + + <!-- if null we are on root level --> + {{if $root.parentBrowseViewModel}} + <li class="browse-list" data-bind="click:function(){displayParentGroupId()}"> + <a href="#">..</a> + </li> + {{/if}} + {{each(i,browseResultEntry) browseResultEntries}} + {{if browseResultEntry.project}} + {{if deleteKarma}} + <li class="browse-list-project"> + <img class="cursor-hand" id="delete-${browseResultEntry.name}" src="images/trash.png" + data-bind="click:function(){deleteProject(groupId,displayEntry(browseResultEntry.name))}"/> + <a href="#" data-bind="click:function(){displayProjectEntry(browseResultEntry.name)}">${displayEntry(browseResultEntry.name)}</a> + <a href="${$root.feedsUrl}/${$root.groupId}/${browseResultEntry.name}"><img src="images/atom.gif"/></a> + </li> + {{else}} + <li class="browse-list-project"> + <a href="#" data-bind="click:function(){displayProjectEntry(browseResultEntry.name)}">${displayEntry(browseResultEntry.name)}</a> + <a href="${$root.feedsUrl}/${$root.groupId}/${browseResultEntry.name}"><img src="images/atom.gif"/></a> + </li> + {{/if}} + {{else}} + {{if deleteKarma}} + <li class="browse-list"> + <img class="cursor-hand" id="delete-${browseResultEntry.name}" src="images/trash.png" + data-bind="click:function(){deleteGroupId(browseResultEntry.name)}"/> + <a data-bind="click:function(){displayGroupId(browseResultEntry.name)}" href="#" + title="folder ${displayEntry(browseResultEntry.name)}">${displayEntry(browseResultEntry.name)}</a> + </li> + {{else}} + <li class="browse-list"> + <a href="#" title="folder ${displayEntry(browseResultEntry.name)}" + data-bind="click:function(){displayGroupId(browseResultEntry.name)}">${displayEntry(browseResultEntry.name)}</a> + </li> + {{/if}} + {{/if}} + + {{/each}} + </ul> + </div> +</script> + +<script id="browse-breadcrumb-tmpl" type="text/html"> + <ul class="breadcrumb"> + <li> + <img class="cursor-hand" src="images/view-refresh.png" data-bind="click: function(){refreshContent()}"/> + </li> + <li> + <a href="#" data-bind="click: function(){ browseRoot()}"><img src="images/go-home.png"/></a> <span + class="divider">/</span> + </li> + {{var number=breadCrumbEntries().length}} + {{each(i,breadCrumbEntry) breadCrumbEntries}} + <li> + {{if i==(number-1)}} + ${breadCrumbEntry.displayValue} + {{else}} + {{if breadCrumbEntry.artifact}} + <a href="#" data-bind="click: function(){goToArtifactDetail(breadCrumbEntry.groupId,breadCrumbEntry.artifactId)}">${breadCrumbEntry.displayValue}</a> + {{else}} + <a href="#" + data-bind="click: function(){displayGroupId(breadCrumbEntry.groupId)}">${breadCrumbEntry.displayValue}</a> + {{/if}} + {{/if}} + {{if i<(number-1)}} + <span class="divider">/</span> + {{/if}} + </li> + {{/each}} + <li> + {{if number>0}} + <span class="divider" id="browse-autocomplete-divider">/</span> + {{/if}} + <input type="text" class="input-large" size="50" id="browse-autocomplete"/> + </li> + </ul> + +</script> + +<script id="browse-artifact-tmpl" type="text/html"> + <div class="row-fluid"> + <div class="span6"> + <div class="page-header"> + <h4>${$.i18n.prop('browse.artifact.display.artifactInfo')}</h4> + </div> + <div id="artifact-info" class="alert alert-info"> + <table class="table table-condensed"> + <tbody> + <tr> + <th>${$.i18n.prop('browse.artifact.groupId')}</th> + <td>${groupId}</td> + </tr> + <tr> + <th>${$.i18n.prop('browse.artifact.artifactId')}</th> + <td>${artifactId}</td> + </tr> + {{if projectVersionMetadata}} + <tr> + <th>${$.i18n.prop('browse.artifact.name')}</th> + <td>${projectVersionMetadata.name}</td> + </tr> + {{/if}} + {{if projectVersionMetadata}} + <tr> + <th>${$.i18n.prop('browse.artifact.description')}</th> + <td>${projectVersionMetadata.description}</td> + </tr> + {{/if}} + {{if projectVersionMetadata && projectVersionMetadata.mavenFacet}} + <tr> + <th>${$.i18n.prop('browse.artifact.packaging')}</th> + <td>${projectVersionMetadata.mavenFacet.packaging}</td> + </tr> + {{/if}} + {{if projectVersionMetadata && projectVersionMetadata.organization}} + <tr> + <th>${$.i18n.prop('browse.artifact.organization.name')}</th> + {{if projectVersionMetadata.organization.url}} + <td> + <a href="${projectVersionMetadata.organization.url}" target="_blank"> + <img src="images/internet-web-browser.png" alt=""/>${projectVersionMetadata.organization.name} + </a> + </td> + {{else}} + <td>${projectVersionMetadata.organization.name}</td> + {{/if}} + </tr> + {{/if}} + {{if projectVersionMetadata && projectVersionMetadata.issueManagement}} + <tr> + <th>${$.i18n.prop('browse.artifact.organization.issueManagement')}</th> + <td> + <a href="${projectVersionMetadata.issueManagement.url}" target="_blank"> + <img src="images/internet-web-browser.png" alt=""/>${projectVersionMetadata.issueManagement.system} + </a> + </td> + </tr> + {{/if}} + </tbody> + </table> + </div> + </div> + <div class="span4"> + <div class="page-header"> + <h4>${$.i18n.prop('browse.artifact.versions')}</h4> + </div> + <div class="alert alert-success"> + <table class="table table-condensed"> + {{each(i,version) versions}} + <tr> + {{if deleteKarma}} + <th><a id="delete-${version}" href="#" data-bind="click: function(){deleteVersion(version)}"><img + src="images/trash.png"/></a> <a href="#" + data-bind="click: function(){displayArtifactVersionDetail(version)}">${version}</a> + </th> + {{else}} + <th><a href="#" data-bind="click: function(){displayArtifactVersionDetail(version)}">${version}</a></th> + {{/if}} + </tr> + {{/each}} + </table> + </div> + </div> + </div> +</script> +<script id="search-artifacts-div-tmpl" type="text/html"> + <div id="search-artifacts-div" data-bind='template:{name:"search-artifacts-form-tmpl"}'></div> +</script> + +<script id="search-artifacts-form-tmpl" type="text/html"> + + <div class="page-header"> + <h3>${$.i18n.prop('search.artifact.header')}</h3> + </div> + <div id="search-artifacts-tabs"> + <div class="tabbable tabs-below"> + <ul class="nav nav-tabs"> + <li class="active" id="search-form-collapse-li"> + <a data-toggle="tab" href="#search-form-collapse">${$.i18n.prop('search.artifact.form.header')}</a> + </li> + <li id="search-results-li"> + <a data-toggle="tab" href="#search-results">${$.i18n.prop('search.artifact.results.header')}</a> + </li> + </ul> + <div class="tab-content"> + + <div id="search-form-collapse" class="tab-pane active"> + <div class="tabbable tabs-below"> + <ul class="nav nav-pills"> + <li class="active"> + <a href="#search-basic-form-pane" + data-toggle="tab">${$.i18n.prop('search.artifact.search.form.basic')}</a> + </li> + <li> + <a href="#search-advanced-form-pane" data-toggle="tab">${$.i18n.prop('search.artifact.search.form.advanced')}</a> + </li> + <li> + <a href="#search-osgi-form-pane" + data-toggle="tab">${$.i18n.prop('search.artifact.search.form.osgi')}</a> + </li> + </ul> + <div class="pill-content"> + <div class="pill-pane active" id="search-basic-form-pane"> + <form class="well form-inline" id="search-basic-form"> + <fieldset> + <div class="control-group" id="search-basic-repositories"> + <select data-placeholder="${$.i18n.prop('search.artifact.search.form.query.repositories')}" + id="search-basic-repositories-select" + multiple style="width:350px;" tabindex="4"> + <option value="all">${$.i18n.prop('search.artifact.search.form.repositories.all')}</option> + {{each(i,repoId) observableRepoIds}} + <option value="${repoId}">${repoId}</option> + {{/each}} + </select> + </div> + <div class="control-group"> + <label class="control-label" for="search-terms"></label> + + <div class="controls"> + <input type="text" class="defaults" id="search-terms" name="search-terms" size="50" + data-bind="value: searchRequest().queryTerms" + placeholder="${$.i18n.prop('search.artifact.search.form.query.terms')}"/> + </div> + </div> + <button type="submit" id="btn-basic-search" class="btn btn-primary" + data-loading-text="${$.i18n.prop('search.artifact.searching')}" + data-bind="click: basicSearch" + accesskey="${$.i18n.prop('search.artifact.search.form.btn.search')[0]}"> + ${$.i18n.prop('search.artifact.search.form.btn.search')} + </button> + </fieldset> + </form> + </div> + <div class="pill-pane" id="search-advanced-form-pane"> + <form class="well form-horizontal" id="search-advanced-form"> + <fieldset> + <div class="control-group"> + <label class="control-label" for="groupId">${$.i18n.prop('search.artifact.search.form.query.groupId')}</label> + + <div class="controls"> + <input type="text" class="defaults" id="groupId" name="groupId" size="50" + placeholder="my.group.id" + data-bind="value: searchRequest().groupId"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="artifactId">${$.i18n.prop('search.artifact.search.form.query.artifactId')}</label> + + <div class="controls"> + <input type="text" class="defaults" id="artifactId" name="artifactId" size="50" + placeholder="my.artifact.id" + data-bind="value: searchRequest().artifactId"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="version">${$.i18n.prop('search.artifact.search.form.query.version')}</label> + + <div class="controls"> + <input type="text" class="defaults" id="version" name="version" size="50" placeholder="0.0.0" + data-bind="value: searchRequest().version"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="classifier">${$.i18n.prop('search.artifact.search.form.query.classifier')}</label> + + <div class="controls"> + <input type="text" class="defaults" id="classifier" name="classifier" size="50" + placeholder="bin" + data-bind="value: searchRequest().classifier"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="packaging">${$.i18n.prop('search.artifact.search.form.query.packaging')}</label> + + <div class="controls"> + <input type="text" class="defaults" id="packaging" name="packaging" size="50" placeholder="jar" + data-bind="value: searchRequest().packaging"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="className">${$.i18n.prop('search.artifact.search.form.query.className')}</label> + + <div class="controls"> + <input type="text" class="defaults" id="className" name="className" size="50" + placeholder="my.ClassName" + data-bind="value: searchRequest().className"/> + </div> + </div> + + </fieldset> + <button type="submit" id="btn-advanced-search" class="btn btn-primary" + data-bind="click: advancedSearch" + accesskey="${$.i18n.prop('search.artifact.search.form.btn.search')[0]}"> + ${$.i18n.prop('search.artifact.search.form.btn.search')} + </button> + + </form> + </div> + <div class="pill-pane" id="search-osgi-form-pane"> + <form class="well form-horizontal" id="search-osgi-form"> + <fieldset> + <div class="control-group"> + <label class="control-label" for="bundleSymbolicName">${$.i18n.prop('search.artifact.search.form.query.bundleSymbolicName')}</label> + + <div class="controls"> + <input type="text" class="defaults" id="bundleSymbolicName" name="bundleSymbolicName" size="50" + placeholder="my.SymbolicName" + data-bind="value: searchRequest().bundleSymbolicName"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="bundleVersion">${$.i18n.prop('search.artifact.search.form.query.bundleVersion')}</label> + + <div class="controls"> + <input type="text" class="defaults" id="bundleVersion" name="bundleVersion" size="50" + placeholder="0.0.0" + data-bind="value: searchRequest().bundleVersion"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="bundleExportPackage">${$.i18n.prop('search.artifact.search.form.query.bundleExportPackage')}</label> + + <div class="controls"> + <input type="text" class="defaults" id="bundleExportPackage" name="bundleExportPackage" + size="50" placeholder="my.package;version=0.0,..." + data-bind="value: searchRequest().bundleExportPackage"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="bundleExportService">${$.i18n.prop('search.artifact.search.form.query.bundleExportService')}</label> + + <div class="controls"> + <input type="text" class="defaults" id="bundleExportService" name="bundleExportService" + size="50" placeholder="my.SomeService" + data-bind="value: searchRequest().bundleExportService"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="bundleImportPackage">${$.i18n.prop('search.artifact.search.form.query.bundleImportPackage')}</label> + + <div class="controls"> + <input type="text" class="defaults" id="bundleImportPackage" name="bundleImportPackage" + size="50" placeholder="my.package;version=0.0,..." + data-bind="value: searchRequest().bundleImportPackage"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="bundleRequireBundle">${$.i18n.prop('search.artifact.search.form.query.bundleRequireBundle')}</label> + + <div class="controls"> + <input type="text" class="defaults" id="bundleRequireBundle" name="bundleRequireBundle" + size="50" placeholder="my.package;version=0.0,..." + data-bind="value: searchRequest().bundleRequireBundle"/> + </div> + </div> + </fieldset> + <button type="submit" id="btn-osgi-search" class="btn btn-primary" + data-bind="click: advancedSearch" + accesskey="${$.i18n.prop('search.artifact.search.form.btn.search')[0]}"> + ${$.i18n.prop('search.artifact.search.form.btn.search')} + </button> + + </form> + </div> + </div> + </div> + </div> + + + <div id="search-results" class="tab-pane"> + <div class="row-fluid"> + <div class="span6"> + <a href="#" class="btn btn-warning" data-bind="click: removeFilter" id="remove-filter-id">${$.i18n.prop('search.artifact.result.filter')}</a> + </div> + <div class="span6" id="search-result-number-div"> + </div> + </div> + <table class="table table-striped table-bordered" id="search-results-grid"> + </table> + <div id="search-results-view-grid-pagination"></div> + + </div> + + </div> + </div> + </div> + +</script> + +<script type="text/html" id="search-result-number-div-tmpl"> + <blockquote> + ${$.i18n.prop('search.artifact.result.size')}: ${resultViewModel.artifacts().length} + </blockquote> + +</script> + +<script id="search-results-view-grid-tmpl" type="text/html"> + <thead> + <tr> + <th title="${$.i18n.prop('search.artifact.results.groupId')}">${$.i18n.prop('search.artifact.results.groupId')}</th> + <th title="${$.i18n.prop('search.artifact.results.artifactId')}"> + ${$.i18n.prop('search.artifact.results.artifactId')} + </th> + <th title="${$.i18n.prop('search.artifact.results.version')}">${$.i18n.prop('search.artifact.results.version')}</th> + <th title="${$.i18n.prop('search.artifact.results.classifier')}"> + ${$.i18n.prop('search.artifact.results.classifier')} + </th> + </tr> + <tr> + + <th title="${$.i18n.prop('search.artifact.results.groupId')}"> + <input type="text" class="form-search" id="search-filter-auto-groupId" + placeholder="${$.i18n.prop('search.artifact.result.grid.filter')}"/> + </th> + <th title="${$.i18n.prop('search.artifact.results.artifactId')}"> + <input type="text" class="form-search" id="search-filter-auto-artifactId" + placeholder="${$.i18n.prop('search.artifact.result.grid.filter')}"/> + </th> + <th title="${$.i18n.prop('search.artifact.results.version')}"> + <input type="text" class="form-search" id="search-filter-auto-version" + placeholder="${$.i18n.prop('search.artifact.result.grid.filter')}"/> + </th> + <th title="${$.i18n.prop('search.artifact.results.classifier')}"> + <input type="text" class="form-search" id="search-filter-auto-classifier" + placeholder="${$.i18n.prop('search.artifact.result.grid.filter')}"/> + </th> + + </tr> + </thead> + <tbody> + {{each(i, row) itemsOnCurrentPage()}} + <tr> + <td><a href="#" data-bind="click: function(){groupIdView(row)}">${row.groupId}</a></td> + <td><a href="#" data-bind="click: function(){artifactIdView(row)}">${row.artifactId}</a></td> + <td><a href="#" data-bind="click: function(){artifactDetailView(row)}">${row.version}</a></td> + <td>${row.classifier}</td> + </tr> + {{/each}} + </tbody> +</script> + + +<script id="selected_repository_tmpl" type="text/html"> + <select id="select_browse_repository" onchange="changeBrowseRepository()"> + <option value="">All</option> + {{each(i,repository) repositories}} + {{if selected && selected==repository.id}} + <option value="${repository.id}" selected>${repository.name}</option> + {{else}} + <option value="${repository.id}">${repository.name}</option> + {{/if}} + {{/each}} + </select> + {{if selected && feedsUrl}} + <a href="${feedsUrl}"><img src="images/atom.gif"/></a> + {{/if}} +</script> + +<script id="browse-artifact-detail-tmpl" type="text/html"> +<ul id="artifact-details-tabs" class="nav nav-tabs"> + <li class="active"> + <a data-toggle="tab" id="artifact-details-info-content-a" data-target="#artifact-details-info-content" + href="#artifact-details-info-content">${$.i18n.prop('artifact.detail.tab.header.info')}</a> + </li> + <li> + <a data-toggle="tab" id="artifact-details-dependencies-content-a" + data-target="#artifact-details-dependencies-content" href="#artifact-details-dependencies-content">${$.i18n.prop('artifact.detail.tab.header.dependencies')}</a> + </li> + <li> + <a data-toggle="tab" id="artifact-details-dependency-tree-content-a" + data-target="#artifact-details-dependency-tree-content" href="#artifact-details-dependency-tree-content">${$.i18n.prop('artifact.detail.tab.header.dependency.tree')}</a> + </li> + <li> + <a data-toggle="tab" id="artifact-details-download-content-a" data-target="#artifact-details-download-content" + href="#artifact-details-download-content">${$.i18n.prop('artifact.detail.tab.header.file.download')}</a> + </li> + <li> + <a data-toggle="tab" id="artifact-details-used-by-content-a" data-target="#artifact-details-used-by-content" + href="#artifact-details-used-by-content">${$.i18n.prop('artifact.detail.tab.header.used.by')}</a> + </li> + <li> + <a data-toggle="tab" id="artifact-details-mailing-list-content-a" + data-target="#artifact-details-mailing-list-content" href="#artifact-details-mailing-list-content">${$.i18n.prop('artifact.detail.tab.header.mailing.list')}</a> + </li> + <li> + <a data-toggle="tab" id="artifact-details-metadatas-content-a" data-target="#artifact-details-metadatas-content" + href="#artifact-details-metadatas-content">${$.i18n.prop('artifact.detail.tab.header.metadatas')}</a> + </li> +</ul> +<div class="tab-content"> +{{if projectVersionMetadata}} +<div id="artifact-details-info-content" class="tab-pane active"> + <blockquote>${projectVersionMetadata.description}</blockquote> + <div class="row-fluid"> + <div class="span6"> + <table class="table"> + <tbody> + <tr> + <th>${$.i18n.prop('browse.artifact.groupId')}</th> + <td>${groupId}</td> + </tr> + <tr> + <th>${$.i18n.prop('browse.artifact.artifactId')}</th> + <td>${artifactId}</td> + </tr> + <tr> + <th>${$.i18n.prop('browse.artifact.version')}</th> + <td>${version}</td> + </tr> + <tr> + <th>${$.i18n.prop('browse.artifact.packaging')}</th> + {{if projectVersionMetadata.mavenFacet}} + <td>${projectVersionMetadata.mavenFacet.packaging}</td> + {{else}} + <td></td> + {{/if}} + </tr> + {{if projectVersionMetadata.mavenFacet}} + {{if projectVersionMetadata.mavenFacet.parent }} + <tr> + <th>${$.i18n.prop('browse.artifact.parent')}</th> + <td> + <a href="#" data-bind="click: displayParent"> + ${projectVersionMetadata.mavenFacet.parent.groupId}:${projectVersionMetadata.mavenFacet.parent.artifactId}:${projectVersionMetadata.mavenFacet.parent.version} + </a> + </td> + </tr> + {{/if}} + {{/if}} + </tbody> + </table> + </div> + <div class="span6"> + <h4>${$.i18n.prop('browse.artifact.pom.snippet')}</h4> + <pre class="prettyprint"><dependency><br/> <groupId>${groupId}</groupId><br/> <artifactId>${artifactId}</artifactId><br/> <version>${version}</version><br/></dependency></pre> + </div> + </div> + <div> + <div class="page-header"> + <h4>${$.i18n.prop('browse.artifact.other.details')}</h4> + </div> + <div> + <div class="row-fluid"> + <div class="span9"> + <table class="table"> + <tbody> + {{if projectVersionMetadata.url}} + <tr> + <th>${$.i18n.prop('browse.artifact.url')}</th> + <td><a href="${projectVersionMetadata.url}" target="_blank">${projectVersionMetadata.url}</a></td> + </tr> + {{/if}} + {{if projectVersionMetadata.organization}} + <tr> + <th>${$.i18n.prop('browse.artifact.organization.name')}</th> + {{if projectVersionMetadata.organization.url}} + <td> + <a href="${projectVersionMetadata.organization.url}" target="_blank"> + <img src="images/internet-web-browser.png" alt=""/>${projectVersionMetadata.organization.name} + </a> + </td> + {{else}} + <td>${projectVersionMetadata.organization.name}</td> + {{/if}} + </tr> + {{/if}} + {{each(i,license) projectVersionMetadata.licenses}} + <tr> + <th>${$.i18n.prop('browse.artifact.license')}</th> + {{if license.url}} + <td> + <a href="${license.url}" target="_blank"> + <img src="images/internet-web-browser.png" alt=""/>${license.name} + </a> + </td> + {{else}} + <td>${license.name}</td> + {{/if}} + </tr> + {{/each}} + {{if projectVersionMetadata.issueManagement}} + <tr> + <th>${$.i18n.prop('browse.artifact.organization.issueManagement')}</th> + <td> + <a href="${projectVersionMetadata.issueManagement.url}" target="_blank"> + <img src="images/internet-web-browser.png" alt=""/>${projectVersionMetadata.issueManagement.system} + </a> + </td> + </tr> + {{/if}} + {{if projectVersionMetadata.ciManagement}} + <tr> + <th>${$.i18n.prop('browse.artifact.organization.ciManagement')}</th> + <td> + <a href="${projectVersionMetadata.ciManagement.url}" target="_blank"> + <img src="images/internet-web-browser.png" alt=""/>${projectVersionMetadata.ciManagement.system} + </a> + </td> + </tr> + {{/if}} + </tbody> + </table> + </div> + </div> + </div> + </div> + {{if projectVersionMetadata.scm}} + <div> + <div class="page-header"> + <h4>${$.i18n.prop('browse.artifact.scm')}</h4> + </div> + <div> + <div class="row-fluid"> + <div class="span12"> + <table class="table"> + <tbody> + <tr> + <th>${$.i18n.prop('browse.artifact.scm.connection')}</th> + <td>${projectVersionMetadata.scm.connection}</td> + </tr> + <tr> + <th>${$.i18n.prop('browse.artifact.scm.devconnection')}</th> + <td>${projectVersionMetadata.scm.developerConnection}</td> + </tr> + <tr> + <th>${$.i18n.prop('browse.artifact.scm.viewer')}</th> + <td><a href="${projectVersionMetadata.scm.url}" target="_blank">${projectVersionMetadata.scm.url}</a></td> + </tr> + </tbody> + </table> + </div> + </div> + </div> + </div> + {{/if}} +</div> +{{/if}} + + +<div id="artifact-details-dependencies-content" class="tab-pane"> + <table class="table table-striped table-bordered" id="artifact-dependencies-table" + data-bind="simpleGrid: gridViewModel,simpleGridTemplate:'ko_dependenciesGrid',pageLinksId:'dependenciesPagination',data:'dependencies'"> + </table> + <div id="dependenciesPagination"></div> +</div> + +<div id="artifact-details-dependency-tree-content" class="tab-pane"></div> + +<div id="artifact-details-files-content" class="tab-pane"></div> + +<div id="artifact-details-download-content" class="tab-pane"></div> + +<div id="artifact-details-used-by-content" class="tab-pane"> + <table class="table table-striped table-bordered" id="artifact-usedby-table"> + </table> + <div id="usedbyPagination"></div> +</div> + +<div id="artifact-details-mailing-list-content" class="tab-pane"> + {{if projectVersionMetadata.mailingLists && projectVersionMetadata.mailingLists.length>0}} + <div id="accordion_mailing_lists" class="accordion"> + {{each(i,mailingList) projectVersionMetadata.mailingLists}} + <div class="accordion-group"> + <div class="accordion-heading"> + <a class="accordion-toggle" href="#ml_collapse_${i}" data-parent="#accordion_mailing_lists" + data-toggle="collapse">${mailingList.name}</a> + </div> + {{if i==0}} + <div id="ml_collapse_${i}" class="accordion-body collapse in"> + {{else}} + <div id="ml_collapse_${i}" class="accordion-body collapse"> + {{/if}} + <div class="accordion-inner"> + {{if mailingList.subscribeAddress}} + <div> + <b>${$.i18n.prop('browse.artifact.mailingList.subscribe')}</b>: <a + href="mailto:${mailingList.subscribeAddress}">${mailingList.subscribeAddress}</a> + </div> + {{/if}} + {{if mailingList.postAddress}} + <div> + <b>${$.i18n.prop('browse.artifact.mailingList.post')}</b>: <a href="mailto:${mailingList.postAddress}">${mailingList.postAddress}</a> + </div> + {{/if}} + {{if mailingList.unsubscribeAddress}} + <div> + <b>${$.i18n.prop('browse.artifact.mailingList.unsubscribe')}</b>: <a + href="mailto:${mailingList.unsubscribeAddress}">${mailingList.unsubscribeAddress}</a> + </div> + {{/if}} + {{if mailingList.mainArchiveUrl}} + <div> + <b>${$.i18n.prop('browse.artifact.mailingList.mainArchiveUrl')}</b>: <a + href="${mailingList.mainArchiveUrl}" target="_blank">${mailingList.mainArchiveUrl}</a> + </div> + {{/if}} + {{if mailingList.otherArchives && mailingList.otherArchives.length>0}} + <div> + <b>${$.i18n.prop('browse.artifact.mailingList.otherArchivesUrls')}:</b> + <ul> + {{each(j,otherArchive) mailingList.otherArchives}} + <li><b>${$.i18n.prop('browse.artifact.mailingList.otherArchiveUrl')}</b>: <a href="${otherArchive}" + target="_blank">${otherArchive}</a> + </li> + {{/each}} + </ul> + </div> + {{/if}} + </div> + </div> + </div> + {{/each}} + </div> + {{else}} + ${$.i18n.prop('browse.artifact.mailingList.none')} + {{/if}} + </div> + + <div id="artifact-details-metadatas-content" class="tab-pane"> + <table class="table table-striped table-bordered" id="artifact-details-metadatas-content-table" + data-bind="simpleGrid: gridMetatadasViewModel,simpleGridTemplate:'artifact_metadata_properties_tmpl',pageLinksId:'artifactMetadata_Pagination'"> + + </table> + <div id="artifactMetadata_Pagination"></div> + {{if hasSavePropertyKarma()}} + <a href="#" class="btn btn-primary" + data-bind="click: addProperty">${$.i18n.prop('browse.artifact.metadatas.add')}</a> + {{/if}} + </div> + +</div> +</div> +</script> + +<script id="ko_dependenciesGrid" type="text/html"> + <tbody> + + + {{each(i, row) itemsOnCurrentPage()}} + <tr> + <th>${row.artifactId}</th> + </tr> + <tr> + <td> + {{var entries=row.crumbEntries()}} + {{each(j,crumbEntry) entries}} + {{if j < entries.length - 2}} + <a href="#" data-bind="click: function(){displayGroup(crumbEntry.groupId)}">${crumbEntry.displayValue}</a> + {{else j == entries.length - 2}} + <a href="#" data-bind="click: function(){displayArtifactDetailView(crumbEntry.groupId,crumbEntry.artifactId)}">${crumbEntry.displayValue}</a> + {{else j == entries.length - 1}} + | <b>${$.i18n.prop('browse.artifact.version')}:</b> + <a href="#" + data-bind="click: function(){displayArtifactVersionDetailViewModel(crumbEntry.groupId,crumbEntry.artifactId,crumbEntry.version)}">${row.version}</a> + {{/if}} + {{if j < entries.length - 2}} + / + {{/if}} + {{/each}} + + {{if row.scope}} + | <b>${$.i18n.prop('browse.artifact.scope')}:</b> ${row.scope} + {{/if}} + </td> + </tr> + {{/each}} + + </tbody> +</script> + +<script id="dependency_tree_tmpl" type="text/html"> + <ul> + {{each(i,treeEntry) treeEntries}} + <li> + {{var entries=treeEntry.artifact.crumbEntries()}} + {{each(j,crumbEntry) entries}} + {{if j < entries.length - 2}} + <a class="cursor-hand" onclick="generalDisplayGroup(encodeURIComponent('${crumbEntry.groupId}'))">${crumbEntry.displayValue}</a> + {{else j == entries.length - 2}} + <a class="cursor-hand" + onclick="generalDisplayArtifactDetailView(encodeURIComponent('${crumbEntry.groupId}'),encodeURIComponent('${crumbEntry.artifactId}'))">${crumbEntry.displayValue}</a> + {{else j == entries.length - 1}} + | <b>${$.i18n.prop('browse.artifact.version')}:</b> + <a class="cursor-hand" + onclick="generalDisplayArtifactVersionDetailViewModel(encodeURIComponent('${crumbEntry.groupId}'),encodeURIComponent('${crumbEntry.artifactId}'),encodeURIComponent('${crumbEntry.version}'))">${crumbEntry.version}</a> + {{/if}} + {{if j < entries.length - 2}} + / + {{/if}} + {{/each}} + </li> + {{if treeEntry.childs.length>0}} + {{tmpl({treeEntries:treeEntry.childs}) "#dependency_tree_tmpl"}} + {{/if}} + {{/each}} + </ul> +</script> + +<script id="dependees_tmpl" type="text/html"> + <ul> + {{each(i, artifact) itemsOnCurrentPage()}} + + <li> + {{var entries=artifact.crumbEntries()}} + {{each(j,crumbEntry) entries}} + {{if j < entries.length - 2}} + <a class="cursor-hand" onclick="generalDisplayGroup(encodeURIComponent('${crumbEntry.groupId}'))">${crumbEntry.displayValue}</a> + {{else j == entries.length - 2}} + <a class="cursor-hand" + onclick="generalDisplayArtifactDetailView(encodeURIComponent('${crumbEntry.groupId}'),encodeURIComponent('${crumbEntry.artifactId}'))">${crumbEntry.displayValue}</a> + {{else j == entries.length - 1}} + | <b>${$.i18n.prop('browse.artifact.version')}:</b> + <a class="cursor-hand" + onclick="generalDisplayArtifactVersionDetailViewModel(encodeURIComponent('${crumbEntry.groupId}'),encodeURIComponent('${crumbEntry.artifactId}'),encodeURIComponent('${crumbEntry.version}'))">${crumbEntry.version}</a> + {{/if}} + {{if j < entries.length - 2}} + / + {{/if}} + {{/each}} + </li> + {{/each}} + </ul> +</script> + +<script id="artifact_metadata_properties_tmpl" type="text/html"> + <thead> + <tr> + <th title="${$.i18n.prop('browse.artifact.metadatas.key')}">${$.i18n.prop('browse.artifact.metadatas.key')}</th> + <th title="${$.i18n.prop('browse.artifact.metadatas.value')}">${$.i18n.prop('browse.artifact.metadatas.value')}</th> + <th title="${$.i18n.prop('browse.artifact.metadatas.delete')}">${$.i18n.prop('browse.artifact.metadatas.delete')} + </th> + <th title="${$.i18n.prop('browse.artifact.metadatas.save')}">${$.i18n.prop('browse.artifact.metadatas.save')}</th> + </tr> + + </thead> + <tbody> + {{each(i, row) itemsOnCurrentPage()}} + <tr> + {{if row.editable && hasSavePropertyKarma()}} + <td><input type="text" data-bind="value: row.key"/></td> + {{else}} + <td>${row.key}</td> + {{/if}} + <td> + {{if hasSavePropertyKarma()}} + <input type="text" data-bind="value: row.value"/> + {{else}} + ${row.value} + {{/if}} + </td> + <td> + {{if hasDeletePropertyKarma()}} + <a href="#" class="btn btn-danger" data-bind="click: function(){deleteProperty(row)}">${$.i18n.prop('browse.artifact.metadatas.delete')}</a> + {{/if}} + </td> + <td> + {{if row.modified && hasSavePropertyKarma()}} + <a href="#" class="btn btn-warning" data-bind="click: function(){saveProperty(row)}">${$.i18n.prop('browse.artifact.metadatas.save')}</a> + {{/if}} + </td> + </tr> + {{/each}} + </tbody> +</script> + +<script id="artifact_content_tree_partial" type="text/html"> + <ul class="jqueryFileTree" style="display: none;"> + {{each artifactContentEntries}} + {{if $value.file == true}} + <li class="file"> + <a href="#" rel="${$value.path}/">${$value.text}</a> + </li> + {{else}} + <li class="directory collapsed"> + <a href="#" rel="${$value.path}/">${$value.text}</a> + </li> + {{/if}} + {{/each}} + </ul> +</script> + +<script id="artifact-details-download-content_tmpl" type="text/html"> + + <div class="row-fluid"> + <div class="span5"> + <ul id="artifact-download-list-files" class="package-list"> + {{each(i, row) artifacts()}} + <li> + <img src="images/system-search-16-16.png" class="cursor-hand" id="${row.classifier}:${row.version}:${row.packaging}" + title="${$.i18n.prop('browse.artifact.content.view.tooltip')}"/> + {{if deleteKarma}} + <a href="#" data-bind="click: function(){deleteArtifact(row)}"> + <img src="images/trash.png" title="${$.i18n.prop('browse.artifact.content.delete.tooltip')}"/> + </a> + + <a href="${row.url}"> + <img src="images/drive-removable-media-16-16.png" title="${$.i18n.prop('browse.artifact.content.download.tooltip')}"/> + </a> + + <span class="text-info">${row.packaging}:${row.version} - ${row.size}</span> + {{else}} + <a href="${row.url}"> + <img src="images/drive-removable-media-16-16.png" title="${$.i18n.prop('browse.artifact.content.download.tooltip')}"/> + </a> + + <span class="text-info">${row.packaging}:${row.version} - ${row.size}</span> + {{/if}} + </li> + {{/each}} + </ul> + </div> + <div class="span7"> + <div id="artifact_content_tree"> + </div> + </div> + </div> + + <h4 id="artifact-content-text-header">${$.i18n.prop('browse.artifact.content.header')}</h4> + + <div class="source"> + <pre class="prettyprint linenums" id="artifact-content-text"></pre> + </div> + +</script>
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/redback/login.html b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/redback/login.html new file mode 100644 index 000000000..6e036cc17 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/redback/login.html @@ -0,0 +1,163 @@ +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the License is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + ~ KIND, either express or implied. See the License for the + ~ specific language governing permissions and limitations + ~ under the License. +--> +<div id="modal-login" class="modal hide fade"> + <div class="modal-header"> + <a href="#" class="close" data-dismiss="modal">×</a> + + <h3>${$.i18n.prop('login.section.title')}</h3> + </div> + <div class="modal-body" id="modal-login-content"> + <form id="user-login-form" class="form-horizontal"> + <div id="modal-login-err-message" class="alert alert-error" style="display:none"></div> + <fieldset> + <div class="control-group"> + <label class="control-label" for="user-login-form-username">${$.i18n.prop('username')}</label> + + <div class="controls"> + <input type="text" id="user-login-form-username" name="user-login-form-username" class="required" + placeholder="${$.i18n.prop('login.username.placehoder')}"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="user-login-form-password">${$.i18n.prop('password')}</label> + + <div class="controls"> + <input type="password" id="user-login-form-password" name="user-login-form-password" class="required" + placeholder="${$.i18n.prop('login.password.placehoder')}"/> + </div> + </div> + </fieldset> + </form> + </div> + <div class="modal-footer" id="modal-login-footer"> + <div class="pull-left"> + <label class="checkbox" id="user-login-form-rememberme-label"> + <input type="checkbox" id="user-login-form-rememberme">${$.i18n.prop('rememberme')} + </label> + </div> + <button class="btn btn-primary" id="modal-login-ok" data-loading-text="${$.i18n.prop('common.loading')}"> + ${$.i18n.prop('login')} + </button> + <button class="btn btn-info" id="modal-login-password-reset">${$.i18n.prop('password.reset')}</button> + </div> +</div> + +<div id="modal-register" class="modal hide fade"> + <div class="modal-header"> + <a href="#" class="close" data-dismiss="modal">×</a> + + <h3>${$.i18n.prop('register.section.title')}</h3> + </div> + <div class="modal-body" id="modal-register-content"> + <form id="user-register-form" class="form-horizontal"> + <div id="modal-register-err-message" class="alert-message error" style="display:none"></div> + <fieldset> + <div class="control-group"> + <label class="control-label" for="user-register-form-username">${$.i18n.prop('username')}</label> + + <div class="controls"> + <input type="text" id="user-register-form-username" name="user-register-form-username" class="required"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="user-register-form-fullname">${$.i18n.prop('full.name')}</label> + + <div class="controls"> + <input type="text" id="user-register-form-fullname" name="user-register-form-fullname" class="required"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="user-register-form-email">${$.i18n.prop('email')}</label> + + <div class="controls"> + <input type="text" id="user-register-form-email" name="user-register-form-email" class="required email"/> + </div> + </div> + + </fieldset> + </form> + </div> + <div class="modal-footer" id="modal-register-footer"> + <button class="btn btn-primary" id="modal-register-ok">${$.i18n.prop('register')}</button> + </div> +</div> + +<div id="modal-password-change" class="modal hide fade"> + <div class="modal-header"> + <a href="#" class="close" data-dismiss="modal">×</a> + + <h3>${$.i18n.prop('password.section.title')}</h3> + </div> + <div class="modal-body" id="modal-password-change-content"> + <form id="password-change-form" class="form-horizontal"> + <div id="modal-password-change-err-message" class="alert-message error" style="display:none"></div> + <fieldset> + <!-- part displayed only when a logged user want to change password will be hide when validate user registration --> + <div class="control-group" id="password-change-form-current-password-div"> + <label class="control-label" + for="password-change-form-current-password">${$.i18n.prop('password.existing')}</label> + + <div class="controls"> + <input type="password" id="password-change-form-current-password" + name="password-change-form-current-password" class="required" value=""/> + </div> + </div> + + <div class="control-group"> + <label class="control-label" for="passwordChangeFormNewPassword">${$.i18n.prop('password.new')}</label> + + <div class="controls"> + <input type="password" id="passwordChangeFormNewPassword" name="passwordChangeFormNewPassword" + class="required" value=""/> + </div> + </div> + + <div class="control-group"> + <label class="control-label" + for="passwordChangeFormNewPasswordConfirm">${$.i18n.prop('password.new.confirm')}</label> + + <div class="controls"> + <input type="password" id="passwordChangeFormNewPasswordConfirm" name="passwordChangeFormNewPasswordConfirm" + class="required" value=""/> + </div> + </div> + </fieldset> + </form> + </div> + <div class="modal-footer" id="modal-password-change-footer"> + <button class="btn btn-primary" onclick="return" id="modal-change-password-ok">${$.i18n.prop('ok')}</button> + </div> +</div> + +<div id="modal-user-edit" class="modal hide fade"> + <div class="modal-header"> + <a href="#" class="close" data-dismiss="modal">×</a> + + <h3>${$.i18n.prop('password.section.title')}</h3> + </div> + <div class="modal-body" id="modal-user-edit-content"> + + </div> + <div class="modal-footer" id="modal-user-edit-footer"> + <button class="btn primary" onclick="return" id="modal-user-edit-ok">${$.i18n.prop('ok')}</button> + </div> +</div> + + + diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/redback/user-edit.html b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/redback/user-edit.html new file mode 100644 index 000000000..9102ce2f0 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/templates/redback/user-edit.html @@ -0,0 +1,572 @@ +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the License is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + ~ KIND, either express or implied. See the License for the + ~ specific language governing permissions and limitations + ~ under the License. +--> +<script id='redback/user-edit-tmpl' type='text/html'> + <div id="edit-user-details-pills"> + <ul id="edit_user_details_pills_headers" class="nav nav-pills" data-target="#edit-user-details-pills-content"> + <li class="active" id="user-view-detail-li"> + <a data-toggle="tab" href="#user-create-div">${$.i18n.prop('edit')}</a> + </li> + <li id="user-edit-roles-edit-li"> + <a data-toggle="tab" href="#user-edit-roles-edit">${$.i18n.prop('effective.roles.edit')}</a> + </li> + </ul> + <div class="pill-content" id="edit-user-details-pills-content"> + <div id="user-create-div" class="active pill-pane"> + <div class="row-fluid"> + <div class="span8 columns"> + <form id="user-create" class="well form-horizontal" data-bind="submit: save"> + <fieldset id="user-create-fieldset"> + <div class="control-group"> + <label class="control-label" for="username">${$.i18n.prop('username')}</label> + + <div class="controls" id="username-div"> + {{if $data.username.length>0}} + <span class="uneditable-input">${$data.username}</span> + {{else}} + <input type="text" id="username" name="username" size="30" class="required" + data-bind="value: username"/> + {{/if}} + </div> + </div> + <div class="control-group"> + <label class="control-label" for="fullname">${$.i18n.prop('full.name')}</label> + + <div class="controls"> + <input type="text" id="fullname" name="fullname" size="30" class="required" + data-bind="value: fullName"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="password">${$.i18n.prop('password')}</label> + + <div class="controls"> + <input type="password" id="password" name="password" class="required" data-bind="value: password"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="confirmPassword">${$.i18n.prop('confirm.password')}</label> + + <div class="controls"> + <input type="password" id="confirmPassword" name="confirmPassword" + data-bind="value: confirmPassword"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="email">${$.i18n.prop('email.address')}</label> + + <div class="controls"> + <input type="text" id="email" name="email" class="required email" data-bind="value: email"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="validated">${$.i18n.prop('validated')}</label> + + <div class="controls"> + <input type="checkbox" id="validated" name="validated" data-bind="checked: validated"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="locked">${$.i18n.prop('locked')}</label> + + <div class="controls"> + <input type="checkbox" id="locked" name="locked" data-bind="checked: locked"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="passwordChangeRequired">${$.i18n.prop('user.change.password.required')}</label> + + <div class="controls"> + <input type="checkbox" id="passwordChangeRequired" name="passwordChangeRequired" + data-bind="checked: passwordChangeRequired"/> + </div> + </div> + </fieldset> + <button data-bind="click: saveUser" class="btn" id="user-create-form-register-button"> + ${$.i18n.prop('save')} + </button> + <button class="btn" id="user-create-form-cancel-button">${$.i18n.prop('cancel')}</button> + </form> + </div> + <div class="span4 columns" id="user-edit-roles"> + <div id="user-edit-roles-view"></div> + </div> + </div> + </div> + + <div id="user-edit-roles-edit" class="pill-pane"> + roles edit + </div> + </div> + </div> +</script> + +<script id="user_view_roles_list_tmpl" type="text/html"> + <div class="page-header"> + <h3>${$.i18n.prop('effective.roles')}</h3> + </div> + <div> + <ul> + {{each $data.user.assignedRoles}} + <li>${$value}</li> + {{/each}} + </ul> + </div> +</script> + +<script id="user_edit_roles_tmpl" type="text/html"> + + <div> + {{each $data.applicationRoles}} + <div class="page-header"> + <h3>${$value.name}</h3> + </div> + <blockquote> + <p>${$value.description}</p> + </blockquote> + <ul> + {{each $value.globalRoles}} + <li><input type="checkbox" value="${$value}" data-bind="checked: user.assignedRoles"> ${$value}</input></li> + {{/each}} + </ul> + + {{if roleTemplates}} + <table class="bordered-table"> + <thead> + <tr> + <th> </th> + {{each roleTemplates}} + <th>${$value.namePrefix}</th> + {{/each}} + </tr> + </thead> + <tbody> + {{each resources}} + {{var curResource = $value}} + <tr> + <td>${curResource}</td> + {{each roleTemplates}} + <td><input type="checkbox" value="${$value.namePrefix}${$value.delimiter}${curResource}" + data-bind="checked: user.assignedRoles"/></td> + {{/each}} + </tr> + {{/each}} + </tbody> + </table> + {{/if}} + + {{/each}} + + <button class="btn" data-bind="click:updateUserRoles">${$.i18n.prop('update')}</button> + + </div> +</script> + +<script id='ko_usersGrid_grid' type='text/html'> + <thead> + <tr> + {{each(i, columnDefinition) columns}} + <th>${ columnDefinition.headerText }</th> + {{/each}} + <th>${$.i18n.prop('edit')}</th> + <th>${$.i18n.prop('delete')}</th> + <th>${$.i18n.prop('user.list.locked')}</th> + <th>${$.i18n.prop('user.change.password.required')}</th> + </tr> + </thead> + <tbody> + {{each(i, row) itemsOnCurrentPage()}} + <tr data-bind="css:{ 'modified': row.modified()}"> + {{each(j, columnDefinition) columns}} + <td> + ${ typeof columnDefinition.rowText == 'function' ? columnDefinition.rowText(row) : row[columnDefinition.rowText] } + </td> + {{/each}} + <td id="users-grid-user-id-${row.username()}"> + <a href="#" data-bind="click: function(){ editUserBox(row) }"> + <span class="btn btn-primary"> + <i class="icon-pencil icon-white"/> + </span> + </a> + </td> + {{if row.username()=="admin" || row.username()=="guest"}} + <td></td> + {{else}} + <td> + <a href="#" data-bind="click: function(){ deleteUser(row) }" id="users-grid-delete-${row.username()}"> + <span class="btn btn-danger"> + <i class="icon-trash icon-white"/> + </span> + </a> + </td> + {{/if}} + + {{if row.locked()==true}} + <td> + <a href="#" data-bind="click: function(){ unlock(row) }"><img src="images/system-lock-screen-22-22.png"/></a> + </td> + {{else}} + <td> + <a href="#" data-bind="click: function(){ lock(row) }"><img src="images/weather-clear-22-22.png"/></a> + </td> + {{/if}} + + {{if row.username()=="admin"}} + <td></td> + {{else}} + {{if row.passwordChangeRequired()==true}} + <td> + <a href="#" data-bind="click: function(){ passwordChangeRequire(row,false) }"> + <img src="images/dialog-error-22-22.png"/> + </a> + </td> + {{else}} + <td> + <a href="#" data-bind="click: function(){ passwordChangeRequire(row,true) }"> + <img src="images/weather-clear-22-22.png"/> + </a> + </td> + {{/if}} + {{/if}} + </tr> + {{/each}} + </tbody> + +</script> + +<script id="usersGrid" type="text/html"> + <div class="page-header"> + <h3><img src="images/system-users-32-32.png"/>${$.i18n.prop('users.list')}</h3> + </div> + <ul id="users-view-tabs" class="nav nav-tabs" data-target="#users-view-tabs-content"> + <li class="active" id="users-view-tabs-li-users-grid"> + <a data-toggle="tab" href="#users-view">${$.i18n.prop('users.grid.tab.title')}</a> + </li> + <li id="users-view-tabs-li-user-edit"> + <a data-toggle="tab" href="#createUserForm" id="users-view-tabs-li-user-edit-a">${$.i18n.prop('add')}</a> + </li> + </ul> + <div id="users-view-tabs-content" class="tab-content"> + <div id="users-view" class="tab-pane"> + <button data-bind='click: sortByName' class="btn"> + ${$.i18n.prop('users.sort.byname')} + </button> + <table class="table table-striped table-bordered" id="usersTable" + data-bind="simpleGrid: gridViewModel,simpleGridTemplate:'ko_usersGrid_grid',pageLinksId:'usersPagination'"> + </table> + <div id="usersPagination"></div> + </div> + <div id="createUserForm" class="tab-pane"></div> + </div> +</script> + +<script id="user-delete-warning-tmpl" type='text/html'> + <div> + <span class="label label-warning">${$.i18n.prop('warning.not.undone.operation')}</span> + </div> +</script> + +<script id="rolesTabs" type="text/html"> + <div class="page-header"> + <h2>${$.i18n.prop('roles.management.header')}</h2> + </div> + + <ul id="roles-view-tabs" class="nav nav-tabs" data-target="roles-view-tabs-content"> + <li class="active" id="roles-view-tabs-li-roles-grid"> + <a data-toggle="tab" href="#roles-view" + id="roles-view-tabs-a-roles-grid">${$.i18n.prop('roles.grid.tab.title')}</a> + </li> + <li id="roles-view-tabs-li-roles-edit"> + <a data-toggle="tab" href="#role-edit">${$.i18n.prop('edit')}</a> + </li> + </ul> + <div id="roles-view-tabs-content" class="tab-content"> + <div id="roles-view" class="tab-pane"> + <div data-bind="style: { display: bulkSave() ? '' : 'none' }"> + <a data-bind="click: updateModifiedRoles" class="btn btn-danger" href="#">${$.i18n.prop('save.all')}</a> + <br/> + </div> + <table class="table table-striped table-bordered" id="rolesTable" + data-bind="simpleGrid: gridViewModel,simpleGridTemplate:'ko_rolesGrid',pageLinksId:'rolesPagination'"> + </table> + <div id="rolesPagination"></div> + </div> + <div id="role-edit" class="tab-pane" data-bind="template: {name:'editRoleTab',data: currentRole}"></div> + </div> + +</script> + +<script id="editRoleTab" type="text/html"> + <div class="accordion" id="edit-role-accordion"> + <div class="accordion-group"> + <div class="accordion-heading"> + <h3> + <a class="accordion-toggle" href="#role-collapse" data-parent="#edit-role-accordion" data-toggle="collapse">${$.i18n.prop('role')}</a> + </h3> + </div> + <div id="role-collapse" class="accordion-body collapse in"> + <table class="table table-bordered" id="editRoleTable"> + <tbody> + <tr> + <td>${$.i18n.prop('name')}:</td> + <td id="role-edit-name">${$data.name}</td> + </tr> + <tr> + <td>${$.i18n.prop('description')}:</td> + <td><input type="text" id="role-edit-description" data-bind="value: description"></td> + </tr> + <tr> + <td colspan="2"> + <div class="pull-left"> + <button class="btn" id="role-edit-description-save" data-bind="click: saveRoleDescription"> + ${$.i18n.prop('save')} + </button> + </div> + </td> + </tr> + </tbody> + </table> + + <div class="page-header"> + <h3>${$.i18n.prop('role.model.parent.roles')}</h3> + </div> + {{if $data.parentRoleNames}} + <ul> + {{each $data.parentRoleNames}} + <li>${$value}</li> + {{/each}} + </ul> + {{/if}} + + <div class="page-header"> + <h3>${$.i18n.prop('role.model.child.roles')}</h3> + </div> + {{if $data.childRoleNames}} + <ul> + {{each $data.childRoleNames}} + <li>${$value}</li> + {{/each}} + </ul> + {{/if}} + + <div class="page-header"> + <h3>${$.i18n.prop('permissions')}</h3> + </div> + {{if $data.permissions}} + <table class="table table-striped table-bordered" id="rolePermissionsTable"> + <thead> + <tr> + <th>${$.i18n.prop('name')}</th> + <th>${$.i18n.prop('role.operation')}</th> + <th>${$.i18n.prop('role.resource')}</th> + </tr> + </thead> + <tbody> + {{each permissions}} + <tr> + <td>${$value.name}</td> + {{if $value.operation }} + <td>${$value.operation().name}</td> + {{else}} + <td></td> + {{/if}} + {{if $value.resource }} + <td>${$value.resource().identifier}</td> + {{else}} + <td></td> + {{/if}} + </tr> + {{/each}} + </tbody> + </table> + {{/if}} + </div> + </div> + <div class="accordion-group>"> + <div class="accordion-heading"> + <h3> + <a class="accordion-toggle" href="#role-users-collapse" data-parent="#edit-role-accordion" + data-toggle="collapse">${$.i18n.prop('role.edit.section.users')}</a> + </h3> + </div> + <div id="role-users-collapse" class="accordion-body collapse"> + {{if $data.parentsRolesUsers}} + <div class="page-header"> + <h3>${$.i18n.prop('role.edit.users.defined.in.parent.roles')}</h3> + </div> + <ul> + {{each $data.parentsRolesUsers}} + <li>${$value.fullName} - ( ${$value.username} - ${$value.email} )</li> + {{/each}} + </ul> + {{/if}} + + <ul id="role-edit-users-tabs" class="nav nav-tabs"> + <li class="active" id="role-view-users-li"> + <a data-toggle="tab" href="#role-view-users">${$.i18n.prop('role.edit.users.list')}</a> + </li> + <li id="role-edit-users-li"> + <a data-toggle="tab" href="#role-edit-users">${$.i18n.prop('edit')}</a> + </li> + </ul> + + <div class="pill-content" id="role-edit-users-tabs-content"> + <div id="role-view-users" class="active pill-pane"> + <div class="page-header"> + <h3>${$.i18n.prop('role.edit.users.defined.in.current.role')}</h3> + </div> + <div id="role-list-users"> + {{if users().length>0}} + <ul> + {{each(j, user) users()}} + <li>${user.fullName()} - ( ${user.username()} - ${user.email()} )</li> + {{/each}} + </ul> + {{else}} + ${$.i18n.prop('role.edit.no.user.defined')} + {{/if}} + </div> + </div> + + <div id="role-edit-users" class="clearfix ar-multiselect pill-pane"> + + <div class="ar-multiselect-column ar-multiselect-left"> + <select data-bind="options: otherUsers ,optionsText: 'username',selectedOptions:selectedOtherUsers" + multiple="true" id="role-edit-available-users"></select> + </div> + <div class="ar-multiselect-column ar-multiselect-center"> + <ul style="list-style: none"> + <li><input class="btn" id="role-edit-users-add-user" type="button" data-bind="click: addUser" + value=">"/></li> + <li><input class="btn" id="role-edit-users-remove-user" type="button" data-bind="click: removeUser" + value="<"/></li> + </ul> + </div> + <div class="ar-multiselect-column ar-multiselect-right"> + <select data-bind="options: users ,optionsText: 'username',selectedOptions:selectedUsers" multiple="true" + id="role-edit-affected-users"></select> + </div> + <button class="btn" id="role-edit-users-save" data-bind="click: saveUsers">${$.i18n.prop('save')}</button> + </div> + </div> + </div> + </div> + </div> +</script> + +<script id='ko_rolesGrid' type='text/html'> + <thead> + <tr> + {{each(i, columnDefinition) columns}} + <th>${ columnDefinition.headerText }</th> + {{/each}} + <th>${$.i18n.prop('edit')}</th> + <th>${$.i18n.prop('save')}</th> + </tr> + </thead> + <tbody> + {{each(i, row) itemsOnCurrentPage()}} + <tr data-bind="css:{ 'modified': row.modified()||row.usersModified()}"> + {{each(j, columnDefinition) columns}} + {{var val = (typeof columnDefinition.rowText == 'function' ? columnDefinition.rowText(row) : + row[columnDefinition.rowText])}} + <td id="role-${columnDefinition.rowText}-${row.name()}"> + ${val} + </td> + {{/each}} + <td> + <a id="edit-role-${row.name()}" href="#" data-bind="click: function(){ editRole(row) }"> + <span class="btn btn-primary"> + <i class="icon-pencil icon-white"/> + </span> + </a> + </td> + <td> + {{if row.modified()}} + <a href="#" class="btn btn-warning" data-bind="click: function(){ updateRole(row) }">${$.i18n.prop('save')}</a> + {{/if}} + </td> + </tr> + {{/each}} +</script> + + +<script type="text/html" id="modal-user-edit-tmpl"> + + <form id="user-edit-form" class="form-horizontal"> + <div id="modal-user-edit-err-message" class="alert-message error" style="display:none"></div> + <fieldset> + <div class="control-group"> + <label class="control-label" for="username">${$.i18n.prop('username')}</label> + + <div class="controls" id="username-div"> + <span class="uneditable-input" data-bind="text: user.username"></span> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="fullname">${$.i18n.prop('full.name')}</label> + + <div class="controls"> + {{if user.readOnly}} + <span class="uneditable-input" data-bind="text: user.fullName"></span> + {{else}} + <input type="text" id="fullname" name="fullname" size="30" class="required" data-bind="value: user.fullName"/> + {{/if}} + </div> + </div> + <div class="control-group"> + <label class="control-label" for="email">${$.i18n.prop('email.address')}</label> + + <div class="controls"> + {{if user.readOnly}} + <span class="uneditable-input" data-bind="text: user.email"></span> + {{else}} + <input type="text" id="email" name="email" size="30" class="required email" data-bind="value: user.email"/> + {{/if}} + </div> + </div> + <div class="control-group" id="user-edit-form-current-password-div"> + <label class="control-label" for="userEditFormCurrentPassword">${$.i18n.prop('password.existing')}</label> + + <div class="controls"> + <input type="password" id="userEditFormCurrentPassword" name="userEditFormCurrentPassword" class="required" + value=""/> + </div> + </div> + + <div class="control-group"> + <label class="control-label" for="userEditFormNewPassword">${$.i18n.prop('password.new')}</label> + + <div class="controls"> + <input type="password" id="userEditFormNewPassword" name="userEditFormNewPassword" class="" value=""/> + </div> + </div> + + <div class="control-group"> + <label class="control-label" for="userEditFormNewPasswordConfirm">${$.i18n.prop('password.new.confirm')}</label> + + <div class="controls"> + <input type="password" id="userEditFormNewPasswordConfirm" name="userEditFormNewPasswordConfirm" class="" + value=""/> + </div> + </div> + </fieldset> + </form> + +</script> + diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/text.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/text.js new file mode 100644 index 000000000..39016dc03 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/text.js @@ -0,0 +1,305 @@ +/** + * @license RequireJS text 2.0.1 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. + * Available via the MIT or new BSD license. + * see: http://github.com/requirejs/text for details + */ +/*jslint regexp: true */ +/*global require: false, XMLHttpRequest: false, ActiveXObject: false, + define: false, window: false, process: false, Packages: false, + java: false, location: false */ + +define(['module'], function (module) { + 'use strict'; + + var progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], + xmlRegExp = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, + bodyRegExp = /<body[^>]*>\s*([\s\S]+)\s*<\/body>/im, + hasLocation = typeof location !== 'undefined' && location.href, + defaultProtocol = hasLocation && location.protocol && location.protocol.replace(/\:/, ''), + defaultHostName = hasLocation && location.hostname, + defaultPort = hasLocation && (location.port || undefined), + buildMap = [], + masterConfig = (module.config && module.config()) || {}, + text, fs; + + text = { + version: '2.0.1', + + strip: function (content) { + //Strips <?xml ...?> declarations so that external SVG and XML + //documents can be added to a document without worry. Also, if the string + //is an HTML document, only the part inside the body tag is returned. + if (content) { + content = content.replace(xmlRegExp, ""); + var matches = content.match(bodyRegExp); + if (matches) { + content = matches[1]; + } + } else { + content = ""; + } + return content; + }, + + jsEscape: function (content) { + return content.replace(/(['\\])/g, '\\$1') + .replace(/[\f]/g, "\\f") + .replace(/[\b]/g, "\\b") + .replace(/[\n]/g, "\\n") + .replace(/[\t]/g, "\\t") + .replace(/[\r]/g, "\\r") + .replace(/[\u2028]/g, "\\u2028") + .replace(/[\u2029]/g, "\\u2029"); + }, + + createXhr: masterConfig.createXhr || function () { + //Would love to dump the ActiveX crap in here. Need IE 6 to die first. + var xhr, i, progId; + if (typeof XMLHttpRequest !== "undefined") { + return new XMLHttpRequest(); + } else if (typeof ActiveXObject !== "undefined") { + for (i = 0; i < 3; i += 1) { + progId = progIds[i]; + try { + xhr = new ActiveXObject(progId); + } catch (e) {} + + if (xhr) { + progIds = [progId]; // so faster next time + break; + } + } + } + + return xhr; + }, + + /** + * Parses a resource name into its component parts. Resource names + * look like: module/name.ext!strip, where the !strip part is + * optional. + * @param {String} name the resource name + * @returns {Object} with properties "moduleName", "ext" and "strip" + * where strip is a boolean. + */ + parseName: function (name) { + var strip = false, index = name.indexOf("."), + modName = name.substring(0, index), + ext = name.substring(index + 1, name.length); + + index = ext.indexOf("!"); + if (index !== -1) { + //Pull off the strip arg. + strip = ext.substring(index + 1, ext.length); + strip = strip === "strip"; + ext = ext.substring(0, index); + } + + return { + moduleName: modName, + ext: ext, + strip: strip + }; + }, + + xdRegExp: /^((\w+)\:)?\/\/([^\/\\]+)/, + + /** + * Is an URL on another domain. Only works for browser use, returns + * false in non-browser environments. Only used to know if an + * optimized .js version of a text resource should be loaded + * instead. + * @param {String} url + * @returns Boolean + */ + useXhr: function (url, protocol, hostname, port) { + var match = text.xdRegExp.exec(url), + uProtocol, uHostName, uPort; + if (!match) { + return true; + } + uProtocol = match[2]; + uHostName = match[3]; + + uHostName = uHostName.split(':'); + uPort = uHostName[1]; + uHostName = uHostName[0]; + + return (!uProtocol || uProtocol === protocol) && + (!uHostName || uHostName.toLowerCase() === hostname.toLowerCase()) && + ((!uPort && !uHostName) || uPort === port); + }, + + finishLoad: function (name, strip, content, onLoad) { + content = strip ? text.strip(content) : content; + if (masterConfig.isBuild) { + buildMap[name] = content; + } + onLoad(content); + }, + + load: function (name, req, onLoad, config) { + //Name has format: some.module.filext!strip + //The strip part is optional. + //if strip is present, then that means only get the string contents + //inside a body tag in an HTML string. For XML/SVG content it means + //removing the <?xml ...?> declarations so the content can be inserted + //into the current doc without problems. + + // Do not bother with the work if a build and text will + // not be inlined. + if (config.isBuild && !config.inlineText) { + onLoad(); + return; + } + + masterConfig.isBuild = config.isBuild; + + var parsed = text.parseName(name), + nonStripName = parsed.moduleName + '.' + parsed.ext, + url = req.toUrl(nonStripName), + useXhr = (masterConfig.useXhr) || + text.useXhr; + + //Load the text. Use XHR if possible and in a browser. + if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) { + text.get(url, function (content) { + text.finishLoad(name, parsed.strip, content, onLoad); + }, function (err) { + if (onLoad.error) { + onLoad.error(err); + } + }); + } else { + //Need to fetch the resource across domains. Assume + //the resource has been optimized into a JS module. Fetch + //by the module name + extension, but do not include the + //!strip part to avoid file system issues. + req([nonStripName], function (content) { + text.finishLoad(parsed.moduleName + '.' + parsed.ext, + parsed.strip, content, onLoad); + }); + } + }, + + write: function (pluginName, moduleName, write, config) { + if (buildMap.hasOwnProperty(moduleName)) { + var content = text.jsEscape(buildMap[moduleName]); + write.asModule(pluginName + "!" + moduleName, + "define(function () { return '" + + content + + "';});\n"); + } + }, + + writeFile: function (pluginName, moduleName, req, write, config) { + var parsed = text.parseName(moduleName), + nonStripName = parsed.moduleName + '.' + parsed.ext, + //Use a '.js' file name so that it indicates it is a + //script that can be loaded across domains. + fileName = req.toUrl(parsed.moduleName + '.' + + parsed.ext) + '.js'; + + //Leverage own load() method to load plugin value, but only + //write out values that do not have the strip argument, + //to avoid any potential issues with ! in file names. + text.load(nonStripName, req, function (value) { + //Use own write() method to construct full module value. + //But need to create shell that translates writeFile's + //write() to the right interface. + var textWrite = function (contents) { + return write(fileName, contents); + }; + textWrite.asModule = function (moduleName, contents) { + return write.asModule(moduleName, fileName, contents); + }; + + text.write(pluginName, nonStripName, textWrite, config); + }, config); + } + }; + + if (typeof process !== "undefined" && + process.versions && + !!process.versions.node) { + //Using special require.nodeRequire, something added by r.js. + fs = require.nodeRequire('fs'); + + text.get = function (url, callback) { + var file = fs.readFileSync(url, 'utf8'); + //Remove BOM (Byte Mark Order) from utf8 files if it is there. + if (file.indexOf('\uFEFF') === 0) { + file = file.substring(1); + } + callback(file); + }; + } else if (text.createXhr()) { + text.get = function (url, callback, errback) { + var xhr = text.createXhr(); + xhr.open('GET', url, true); + + //Allow overrides specified in config + if (masterConfig.onXhr) { + masterConfig.onXhr(xhr, url); + } + + xhr.onreadystatechange = function (evt) { + var status, err; + //Do not explicitly handle errors, those should be + //visible via console output in the browser. + if (xhr.readyState === 4) { + status = xhr.status; + if (status > 399 && status < 600) { + //An http 4xx or 5xx error. Signal an error. + err = new Error(url + ' HTTP status: ' + status); + err.xhr = xhr; + errback(err); + } else { + callback(xhr.responseText); + } + } + }; + xhr.send(null); + }; + } else if (typeof Packages !== 'undefined') { + //Why Java, why is this so awkward? + text.get = function (url, callback) { + var encoding = "utf-8", + file = new java.io.File(url), + lineSeparator = java.lang.System.getProperty("line.separator"), + input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)), + StringBuilder, line, + content = ''; + try { + StringBuilder = new java.lang.StringBuilder(); + line = input.readLine(); + + // Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324 + // http://www.unicode.org/faq/utf_bom.html + + // Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK: + // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058 + if (line && line.length() && line.charAt(0) === 0xfeff) { + // Eat the BOM, since we've already found the encoding on this file, + // and we plan to concatenating this buffer with others; the BOM should + // only appear at the top of a file. + line = line.substring(1); + } + + StringBuilder.append(line); + + while ((line = input.readLine()) !== null) { + StringBuilder.append(lineSeparator); + StringBuilder.append(line); + } + //Make sure we return a JavaScript string and not a Java string. + content = String(StringBuilder.toString()); //String + } finally { + input.close(); + } + callback(content); + }; + } + + return text; +}); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/tmpl.min.js b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/tmpl.min.js new file mode 100644 index 000000000..065532e7c --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/tmpl.min.js @@ -0,0 +1 @@ +(function(a){"use strict";var b=function(a,c){var d=/[^\w\-\.:]/.test(a)?new Function(b.arg+",tmpl","var _e=tmpl.encode"+b.helper+",_s='"+a.replace(b.regexp,b.func)+"';return _s;"):b.cache[a]=b.cache[a]||b(b.load(a));return c?d(c,b):function(a){return d(a,b)}};b.cache={},b.load=function(a){return document.getElementById(a).innerHTML},b.regexp=/([\s'\\])(?![^%]*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g,b.func=function(a,b,c,d,e,f){if(b)return{"\n":"\\n","\r":"\\r","\t":"\\t"," ":" "}[a]||"\\"+a;if(c)return c==="="?"'+_e("+d+")+'":"'+("+d+"||'')+'";if(e)return"';";if(f)return"_s+='"},b.encReg=/[<>&"'\x00]/g,b.encMap={"<":"<",">":">","&":"&",'"':""","'":"'"},b.encode=function(a){return String(a||"").replace(b.encReg,function(a){return b.encMap[a]||""})},b.arg="o",b.helper=",print=function(s,e){_s+=e&&(s||'')||_e(s);},include=function(s,d){_s+=tmpl(s,d);}",typeof define=="function"&&define.amd?define(function(){return b}):a.tmpl=b})(this);
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/test/tomcat/auto-admin-creation.properties b/archiva-modules/archiva-web/archiva-webapp/src/test/tomcat/auto-admin-creation.properties new file mode 100644 index 000000000..7c8c5815b --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/test/tomcat/auto-admin-creation.properties @@ -0,0 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +redback.admin.fullname=Archiva Admin +redback.admin.email=admin@toto.com +redback.admin.password=admin123
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/test/tomcat/log4j2-test.xml b/archiva-modules/archiva-web/archiva-webapp/src/test/tomcat/log4j2-test.xml new file mode 100644 index 000000000..5537a174f --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/test/tomcat/log4j2-test.xml @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the License is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + ~ KIND, either express or implied. See the License for the + ~ specific language governing permissions and limitations + ~ under the License. + --> + + +<configuration status="debug"> + + <properties> + <property name="logsDirectory">${sys:appserver.base}/logs</property> + </properties> + + <appenders> + <Console name="console" target="SYSTEM_OUT"> + <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> + </Console> + + <!--RollingFile name="console" fileName="${logsDirectory}/archiva.log" + filePattern="${logsDirectory}/archiva-%d{MM-dd-yyyy}.log"> + <PatternLayout> + <pattern>%d [%t] %-5p %c %x - %m%n</pattern> + </PatternLayout> + <Policies> + <TimeBasedTriggeringPolicy /> + </Policies> + </RollingFile--> + + </appenders> + <loggers> + + <!-- apache httpclient debug content transfer--> + <!-- + <logger name="org.apache.http.wire"> + <level value="debug"/> + </logger> + <logger name="org.apache.http.headers" level="debug"/> + --> + + + <logger name="org.apache.archiva.indexer.search.MavenRepositorySearch" level="info"/> + + <logger name="org.apache.archiva.common.plexusbridge.MavenIndexerUtils" level="info"/> + + <logger name="JPOX" level="error"/> + + + <logger name="org.apache.commons.configuration.DefaultConfigurationBuilder" level="error"/> + + + <logger name="org.apache.archiva.admin.repository.managed" level="info"/> + + <logger name="org.springframework" level="info"/> + + + <logger name="org.codehaus.plexus" level="info"/> + + + <logger name="org.codehaus.redback" level="info"/> + + + <logger name="org.apache.cxf" level="info"/> + + <logger name="org.quartz" level="info"/> + + <logger name="org.apache.archiva.indexer.merger" level="info"/> + + <logger name="org.apache.archiva.metadata.repository.stats.DefaultRepositoryStatisticsManager" level="debug" /> + + <logger name="org.apache.archiva.scheduler.repository.DefaultRepositoryArchivaTaskScheduler" level="debug"/> + + <root level="info"> + <appender-ref ref="console"/> + </root> + </loggers> +</configuration> + + diff --git a/archiva-modules/archiva-web/archiva-webapp/src/test/tomcat/tomcat-context-archiva.xml b/archiva-modules/archiva-web/archiva-webapp/src/test/tomcat/tomcat-context-archiva.xml new file mode 100644 index 000000000..4f7ce1d69 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/test/tomcat/tomcat-context-archiva.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the License is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + ~ KIND, either express or implied. See the License for the + ~ specific language governing permissions and limitations + ~ under the License. + --> +<Context path="/archiva"> + <Resource name="jdbc/users" auth="Container" type="javax.sql.DataSource" + username="sa" + password="" + driverClassName="org.apache.derby.jdbc.EmbeddedDriver" + url="jdbc:derby:${appserver.base}/database/users;create=true" + /> + <Resource name="mail/Session" auth="Container" + type="javax.mail.Session" + mail.smtp.host="localhost"/> + +</Context> |