diff --git a/pom.xml b/pom.xml index 35694f036..7f843de09 100644 --- a/pom.xml +++ b/pom.xml @@ -17,6 +17,12 @@ https://webgoat.github.io/ + + org.springframework.boot + spring-boot-starter-parent + 1.3.3.RELEASE + + GNU General Public License, version 2 @@ -148,7 +154,6 @@ 2.19 2.6 1.6.6 - 3.2.4.RELEASE 2.1.20 2.48.2 1.7.12 diff --git a/webgoat-container/pom.xml b/webgoat-container/pom.xml index 800862192..b562a4759 100644 --- a/webgoat-container/pom.xml +++ b/webgoat-container/pom.xml @@ -12,6 +12,10 @@ 7.1-SNAPSHOT + + org.owasp.webgoat.WebGoat + + run-integration-tests @@ -206,10 +210,49 @@ + + org.springframework.boot + spring-boot-maven-plugin + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter + + + org.apache.tomcat.embed + tomcat-embed-jasper + provided + + + + + + + + javax.servlet + jstl + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.xeustechnologies + jcl-core + 2.7 + javax.activation activation @@ -266,16 +309,16 @@ - - commons-logging - commons-logging - ${commons-logging.version} - - - org.slf4j - jcl-over-slf4j - ${jcl-over-slf4j.version} - + + + + + + + + + + commons-discovery commons-discovery @@ -316,71 +359,33 @@ jtds ${jtds.version} - - org.apache.tomcat - tomcat-catalina - ${tomcat-catalina.version} - provided - + + + + + + - - javax - javaee-api - ${javaee-api.version} - provided - + + + + + + - - org.springframework - spring-core - ${org.springframework.version} - - - org.springframework - spring-aop - ${org.springframework.version} - com.fasterxml.jackson.core jackson-core - ${jackson-core.version} com.fasterxml.jackson.core jackson-databind - ${jackson-databind.version} - - - - - org.springframework - spring-webmvc - ${org.springframework.version} - jar - - - - org.springframework.security - spring-security-core - ${spring.security.version} - - - - org.springframework.security - spring-security-config - ${spring.security.version} - - - - org.springframework.security - spring-security-web - ${spring.security.version} @@ -409,43 +414,43 @@ ${standard.version} - - log4j - log4j - ${log4j.version} - - - javax.jms - jms - - - com.sun.jdmk - jmxtools - - - com.sun.jmx - jmxri - - - + + + + + + + + + + + + + + + + + + + org.apache.tiles tiles-core ${tiles.version} jar - - org.slf4j - slf4j-api - ${slf4j-api.version} - jar - - - org.slf4j - slf4j-log4j12 - ${slf4j-log4j12.version} - jar - + + + + + + + + + + + + diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/HammerHead.java b/webgoat-container/src/main/java/org/owasp/webgoat/HammerHead.java index 8af97ff56..13ad3ea3c 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/HammerHead.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/HammerHead.java @@ -204,7 +204,7 @@ public class HammerHead extends HttpServlet { private String getViewPage(WebSession webSession) { // now always display the lesson content - String page = "/lesson_content.jsp"; + String page = "lesson_content"; //page = "/main.jsp"; return page; } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/MvcConfiguration.java b/webgoat-container/src/main/java/org/owasp/webgoat/MvcConfiguration.java new file mode 100644 index 000000000..eef807209 --- /dev/null +++ b/webgoat-container/src/main/java/org/owasp/webgoat/MvcConfiguration.java @@ -0,0 +1,33 @@ +package org.owasp.webgoat; + +import org.owasp.webgoat.session.LabelDebugger; +import org.springframework.boot.context.embedded.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +/** + * + */ +@Configuration +public class MvcConfiguration extends WebMvcConfigurerAdapter { + + + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/login").setViewName("login"); + registry.addViewController("/lesson_content").setViewName("lesson_content"); + } + + @Bean + public ServletRegistrationBean servletRegistrationBean() { + return new ServletRegistrationBean(new HammerHead(), "/attack/*"); + } + + @Bean + //@Scope(value= WebApplicationContext.SCOPE_SESSION) + public LabelDebugger labelDebugger() { + return new LabelDebugger(); + } +} \ No newline at end of file diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/WebGoat.java b/webgoat-container/src/main/java/org/owasp/webgoat/WebGoat.java new file mode 100644 index 000000000..8d96a05a6 --- /dev/null +++ b/webgoat-container/src/main/java/org/owasp/webgoat/WebGoat.java @@ -0,0 +1,53 @@ +package org.owasp.webgoat; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.context.web.SpringBootServletInitializer; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; + +@SpringBootApplication +public class WebGoat extends SpringBootServletInitializer { + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(WebGoat.class); + } + + @Override + public void onStartup(ServletContext servletContext) throws ServletException { + super.onStartup(servletContext); + + } + + public static void main(String[] args) throws Exception { + SpringApplication.run(WebGoat.class, args); + } + +// @Bean +// @Autowired +// public TomcatEmbeddedServletContainerFactory servletContainer(final JarScanner jarScanner) { +// TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory(); +// factory.setPort(80); +// factory.setSessionTimeout(10, TimeUnit.MINUTES); +// factory.addContextCustomizers(new TomcatContextCustomizer() { +// @Override +// public void customize(Context context) { +// +// context.setJarScanner(jarScanner); +// } +// }); +// return factory; +// } +// +// @Bean +// public JarScanner getJarScanner() { +// StandardJarScanner jarScanner = new StandardJarScanner(); +// jarScanner.setScanClassPath(true); +// return jarScanner; +// } + + +} diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/WebSecurityConfig.java b/webgoat-container/src/main/java/org/owasp/webgoat/WebSecurityConfig.java new file mode 100644 index 000000000..097a9e08d --- /dev/null +++ b/webgoat-container/src/main/java/org/owasp/webgoat/WebSecurityConfig.java @@ -0,0 +1,49 @@ +package org.owasp.webgoat; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; +import org.springframework.security.core.userdetails.UserDetailsService; + +@Configuration +@EnableWebSecurity +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + @Override + protected void configure(HttpSecurity http) throws Exception { + ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry security = http + .authorizeRequests() + .antMatchers("/css/**", "/images/**", "/js/**", "fonts/**", "/plugins/**").permitAll() + .antMatchers("/servlet/AdminServlet/**").hasAnyRole("WEBGOAT_ADMIN", "SERVER_ADMIN") // + .antMatchers("/JavaSource/**").hasRole("SERVER_ADMIN") // + .anyRequest().hasAnyRole("WEBGOAT_USER", "WEBGOAT_ADMIN", "SERVER_ADMIN"); + security.and() + .formLogin() + .loginPage("/login") + .defaultSuccessUrl("/welcome.mvc") + .usernameParameter("username") + .passwordParameter("password") + .permitAll(); + security.and() + .logout() + .permitAll(); + } + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication() + .withUser("guest").password("guest").roles("WEBGOAT_USER").and() // + .withUser("webgoat").password("webgoat").roles("WEBGOAT_ADMIN").and() // + .withUser("server").password("server").roles("SERVER_ADMIN"); + } + + @Bean + @Override + public UserDetailsService userDetailsServiceBean() throws Exception { + return super.userDetailsServiceBean(); + } +} \ No newline at end of file diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/controller/About.java b/webgoat-container/src/main/java/org/owasp/webgoat/controller/About.java deleted file mode 100644 index 094d9285f..000000000 --- a/webgoat-container/src/main/java/org/owasp/webgoat/controller/About.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.owasp.webgoat.controller; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.servlet.ModelAndView; - -/** - *

About class.

- * - * @author rlawson - * @version $Id: $Id - */ -@Controller -public class About { - - final Logger logger = LoggerFactory.getLogger(About.class); - private static final String WELCOMED = "welcomed"; - - /** - *

welcome.

- * - * @param request a {@link javax.servlet.http.HttpServletRequest} object. - * @param error a {@link java.lang.String} object. - * @param logout a {@link java.lang.String} object. - * @return a {@link org.springframework.web.servlet.ModelAndView} object. - */ - @RequestMapping(value = "about.mvc", method = RequestMethod.GET) - public ModelAndView welcome(HttpServletRequest request, - @RequestParam(value = "error", required = false) String error, - @RequestParam(value = "logout", required = false) String logout) { - - // set the welcome attribute - // this is so the attack servlet does not also - // send them to the welcome page - HttpSession session = request.getSession(); - if (session.getAttribute(WELCOMED) == null) { - session.setAttribute(WELCOMED, "true"); - } - - //go ahead and send them to webgoat (skip the welcome page) - ModelAndView model = new ModelAndView(); - //model.setViewName("welcome"); - //model.setViewName("main_new"); - model.setViewName("about"); - return model; - } - -} diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/controller/Login.java b/webgoat-container/src/main/java/org/owasp/webgoat/controller/Login.java index 6f9021f19..2372cceb5 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/controller/Login.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/controller/Login.java @@ -5,44 +5,38 @@ */ package org.owasp.webgoat.controller; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.servlet.ModelAndView; - /** *

Login class.

* * @author rlawson * @version $Id: $Id */ -@Controller +//@Controller public class Login { - /** - *

login.

- * - * @param error a {@link java.lang.String} object. - * @param logout a {@link java.lang.String} object. - * @return a {@link org.springframework.web.servlet.ModelAndView} object. - */ - @RequestMapping(value = "login.mvc", method = RequestMethod.GET) - public ModelAndView login( - @RequestParam(value = "error", required = false) String error, - @RequestParam(value = "logout", required = false) String logout) { - - ModelAndView model = new ModelAndView(); - if (error != null) { - model.addObject("error", "Invalid username and password!"); - } - - if (logout != null) { - model.addObject("msg", "You've been logged out successfully."); - } - model.setViewName("login"); - - return model; - - } +// /** +// *

login.

+// * +// * @param error a {@link java.lang.String} object. +// * @param logout a {@link java.lang.String} object. +// * @return a {@link org.springframework.web.servlet.ModelAndView} object. +// */ +// @RequestMapping(path = "login.mvc", method = RequestMethod.GET) +// public ModelAndView login( +// @RequestParam(value = "error", required = false) String error, +// @RequestParam(value = "logout", required = false) String logout) { +// +// ModelAndView model = new ModelAndView(); +// if (error != null) { +// model.addObject("error", "Invalid username and password!"); +// } +// +// if (logout != null) { +// model.addObject("msg", "You've been logged out successfully."); +// } +// model.setViewName("login"); +// +// return model; +// +// } } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/controller/Logout.java b/webgoat-container/src/main/java/org/owasp/webgoat/controller/Logout.java index 92e236a1c..0ef685d5f 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/controller/Logout.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/controller/Logout.java @@ -31,7 +31,7 @@ public class Logout { * @param logout a {@link java.lang.String} object. * @return a {@link org.springframework.web.servlet.ModelAndView} object. */ - @RequestMapping(value = "logout.mvc", method = RequestMethod.GET) + @RequestMapping(path = "logout.mvc", method = RequestMethod.GET) public ModelAndView logout( @RequestParam(value = "error", required = false) String error, @RequestParam(value = "logout", required = false) String logout) { diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/controller/Start.java b/webgoat-container/src/main/java/org/owasp/webgoat/controller/Start.java index 300209a9d..d2a645d37 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/controller/Start.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/controller/Start.java @@ -5,10 +5,6 @@ */ package org.owasp.webgoat.controller; -import java.util.Collection; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; import org.apache.commons.lang3.StringUtils; import org.owasp.webgoat.application.Application; import org.owasp.webgoat.session.WebSession; @@ -20,9 +16,13 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.util.Collection; + /** *

Start class.

* @@ -43,14 +43,10 @@ public class Start { *

start.

* * @param request a {@link javax.servlet.http.HttpServletRequest} object. - * @param error a {@link java.lang.String} object. - * @param logout a {@link java.lang.String} object. * @return a {@link org.springframework.web.servlet.ModelAndView} object. */ - @RequestMapping(value = "start.mvc", method = {RequestMethod.GET, RequestMethod.POST}) - public ModelAndView start(HttpServletRequest request, - @RequestParam(value = "error", required = false) String error, - @RequestParam(value = "logout", required = false) String logout) { + @RequestMapping(path = "start.mvc", method = {RequestMethod.GET, RequestMethod.POST}) + public ModelAndView start(HttpServletRequest request) { ModelAndView model = new ModelAndView(); // make sure session is set up correctly diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/controller/Welcome.java b/webgoat-container/src/main/java/org/owasp/webgoat/controller/Welcome.java index 050b0a79f..b1ab03f8a 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/controller/Welcome.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/controller/Welcome.java @@ -5,16 +5,14 @@ */ package org.owasp.webgoat.controller; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + /** *

Welcome class.

* @@ -23,22 +21,17 @@ import org.springframework.web.servlet.ModelAndView; */ @Controller public class Welcome { - - final Logger logger = LoggerFactory.getLogger(Welcome.class); + private static final String WELCOMED = "welcomed"; /** *

welcome.

* * @param request a {@link javax.servlet.http.HttpServletRequest} object. - * @param error a {@link java.lang.String} object. - * @param logout a {@link java.lang.String} object. * @return a {@link org.springframework.web.servlet.ModelAndView} object. */ - @RequestMapping(value = "welcome.mvc", method = RequestMethod.GET) - public ModelAndView welcome(HttpServletRequest request, - @RequestParam(value = "error", required = false) String error, - @RequestParam(value = "logout", required = false) String logout) { + @RequestMapping(path = "welcome.mvc", method = RequestMethod.GET) + public ModelAndView welcome(HttpServletRequest request) { // set the welcome attribute // this is so the attack servlet does not also diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/AbstractLesson.java b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/AbstractLesson.java index 5598af3b1..91c509fa5 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/AbstractLesson.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/AbstractLesson.java @@ -259,7 +259,7 @@ public abstract class AbstractLesson extends Screen implements Comparable lesson; private Map solutionLanguageFiles = new HashMap<>(); @@ -35,6 +35,10 @@ public class Plugin { private List pluginFiles = Lists.newArrayList(); private File lessonSourceFile; + public Plugin(PluginClassLoader classLoader) { + this.classLoader = classLoader; + } + /** *

findLesson.

* @@ -49,10 +53,10 @@ public class Plugin { private void findLesson(String name) { String realClassName = StringUtils.trimLeadingCharacter(name, '/').replaceAll("/", ".").replaceAll(".class", ""); //TODO should be passed in (refactor) - WebappClassLoader cl = (WebappClassLoader) Thread.currentThread().getContextClassLoader(); + //TomcatEmbeddedWebappClassLoader cl = (TomcatEmbeddedWebappClassLoader) Thread.currentThread().getContextClassLoader(); try { - Class clazz = cl.loadClass(realClassName, true); + Class clazz = classLoader.loadClass(realClassName); if (AbstractLesson.class.isAssignableFrom(clazz)) { this.lesson = clazz; diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginClassLoader.java b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginClassLoader.java new file mode 100644 index 000000000..24aa42041 --- /dev/null +++ b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginClassLoader.java @@ -0,0 +1,16 @@ +package org.owasp.webgoat.plugins; + +import java.net.URL; +import java.net.URLClassLoader; + +public class PluginClassLoader extends URLClassLoader { + + public PluginClassLoader(ClassLoader parent) { + super(new URL[] {}, parent); + } + + @Override + public void addURL(URL url) { + super.addURL(url); + } +} diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginExtractor.java b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginExtractor.java index 1d7b1cf24..d8b9681d5 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginExtractor.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginExtractor.java @@ -34,9 +34,9 @@ public class PluginExtractor { * @return a {@link org.owasp.webgoat.plugins.Plugin} object. * @throws java.io.IOException if any. */ - public Plugin extractJarFile(final File archive, final File targetDirectory) throws IOException { + public Plugin extractJarFile(final File archive, final File targetDirectory, PluginClassLoader cl) throws IOException { ZipFile zipFile = new ZipFile(archive); - Plugin plugin = new Plugin(); + Plugin plugin = new Plugin(cl); try { Enumeration entries = zipFile.entries(); while (entries.hasMoreElements()) { diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginsLoader.java b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginsLoader.java index 1d9731bb0..2e23f8ce3 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginsLoader.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginsLoader.java @@ -1,7 +1,6 @@ package org.owasp.webgoat.plugins; import com.google.common.collect.Lists; -import org.apache.catalina.loader.WebappClassLoader; import org.apache.commons.io.FileUtils; import org.owasp.webgoat.util.LabelProvider; import org.slf4j.Logger; @@ -48,24 +47,25 @@ public class PluginsLoader { this.pluginTarget = Objects.requireNonNull(pluginTarget, "plugin target cannot be null"); } - /** - * Copy jars to the lib directory - */ - public void copyJars() { - try { - if (!alreadyLoaded) { - WebappClassLoader cl = (WebappClassLoader) Thread.currentThread().getContextClassLoader(); - cl.setAntiJARLocking(true); - List jars = listJars(); - for (URL jar : jars) { - cl.addRepository(jar.toString()); - } - alreadyLoaded = true; - } - } catch (Exception e) { - logger.error("Copying plugins failed", e); - } - } +// /** +// * Copy jars to the lib directory +// */ +// public void copyJars() { +// try { +// if (!alreadyLoaded) { +// WebappClassLoader cl = (WebappClassLoader) Thread.currentThread().getContextClassLoader(); +// // cl.setAntiJARLocking(true); +// List jars = listJars(); +// for (URL jar : jars) { +// // cl.setResources(); +// // cl.addRepository(jar.toString()); +// } +// alreadyLoaded = true; +// } +// } catch (Exception e) { +// logger.error("Copying plugins failed", e); +// } +// } /** *

loadPlugins.

@@ -73,7 +73,7 @@ public class PluginsLoader { * @return a {@link java.util.List} object. */ public List loadPlugins() { - copyJars(); + // copyJars(); List plugins = Lists.newArrayList(); try { @@ -134,13 +134,17 @@ public class PluginsLoader { private List> extractJars(List jars) { List> extractorCallables = Lists.newArrayList(); + ClassLoader parentClassLoader = PluginClassLoader.class.getClassLoader(); + final PluginClassLoader classLoader = new PluginClassLoader(parentClassLoader); + for (final URL jar : jars) { + classLoader.addURL(jar); extractorCallables.add(new Callable() { @Override public Plugin call() throws Exception { PluginExtractor extractor = new PluginExtractor(); - return extractor.extractJarFile(ResourceUtils.getFile(jar), pluginTarget.toFile()); + return extractor.extractJarFile(ResourceUtils.getFile(jar), pluginTarget.toFile(), classLoader); } }); } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/ApplicationService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/ApplicationService.java index e348f67bd..d05d5be84 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/ApplicationService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/ApplicationService.java @@ -29,12 +29,13 @@ */ package org.owasp.webgoat.service; -import javax.servlet.http.HttpSession; import org.owasp.webgoat.application.Application; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; +import javax.servlet.http.HttpSession; + /** *

ApplicationService class.

* @@ -50,7 +51,7 @@ public class ApplicationService extends BaseService { * @param session a {@link javax.servlet.http.HttpSession} object. * @return a {@link org.owasp.webgoat.application.Application} object. */ - @RequestMapping(value = "/application.mvc", produces = "application/json") + @RequestMapping(path = "/application.mvc", produces = "application/json") public @ResponseBody Application showApplication(HttpSession session) { Application app = Application.getInstance(); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/CookieService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/CookieService.java index 5edd61323..69dd9e8fa 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/CookieService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/CookieService.java @@ -29,10 +29,6 @@ */ package org.owasp.webgoat.service; -import java.util.Collections; -import java.util.List; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpSession; import org.owasp.webgoat.lessons.model.RequestParameter; import org.owasp.webgoat.session.WebSession; import org.springframework.stereotype.Controller; @@ -40,6 +36,11 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpSession; +import java.util.Collections; +import java.util.List; + /** *

CookieService class.

* @@ -55,7 +56,7 @@ public class CookieService extends BaseService { * @param session a {@link javax.servlet.http.HttpSession} object. * @return a {@link java.util.List} object. */ - @RequestMapping(value = "/cookie.mvc", produces = "application/json") + @RequestMapping(path = "/cookie.mvc", produces = "application/json") public @ResponseBody List showCookies(HttpSession session) { WebSession ws = getWebSession(session); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/HintService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/HintService.java index 20cd36691..5efcdaf87 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/HintService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/HintService.java @@ -32,7 +32,7 @@ public class HintService extends BaseService { * @param session a {@link javax.servlet.http.HttpSession} object. * @return a {@link java.util.List} object. */ - @RequestMapping(value = "/hint.mvc", produces = "application/json") + @RequestMapping(path = "/hint.mvc", produces = "application/json") public @ResponseBody List showHint(HttpSession session) { List listHints = new ArrayList(); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/LabelDebugService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/LabelDebugService.java index c00fc20f9..937e11a33 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/LabelDebugService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/LabelDebugService.java @@ -68,7 +68,7 @@ public class LabelDebugService extends BaseService { * * @return a {@link org.springframework.http.ResponseEntity} object. */ - @RequestMapping(value = URL_DEBUG_LABELS_MVC, produces = MediaType.APPLICATION_JSON_VALUE) + @RequestMapping(path = URL_DEBUG_LABELS_MVC, produces = MediaType.APPLICATION_JSON_VALUE) public @ResponseBody ResponseEntity> checkDebuggingStatus() { logger.debug("Checking label debugging, it is " + labelDebugger.isEnabled()); // FIXME parameterize diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonInfoService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonInfoService.java index b334c4720..40dee8e3f 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonInfoService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonInfoService.java @@ -32,7 +32,7 @@ public class LessonInfoService extends BaseService { * @param session a {@link javax.servlet.http.HttpSession} object. * @return a {@link org.owasp.webgoat.lessons.model.LessonInfoModel} object. */ - @RequestMapping(value = "/lessoninfo.mvc", produces = "application/json") + @RequestMapping(path = "/lessoninfo.mvc", produces = "application/json") public @ResponseBody LessonInfoModel getLessonInfo(HttpSession session) { WebSession webSession = getWebSession(session); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonMenuService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonMenuService.java index 20f5d8cee..2cf0f3522 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonMenuService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonMenuService.java @@ -29,9 +29,6 @@ */ package org.owasp.webgoat.service; -import java.util.ArrayList; -import java.util.List; -import javax.servlet.http.HttpSession; import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Category; import org.owasp.webgoat.lessons.RandomLessonAdapter; @@ -45,6 +42,10 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; +import javax.servlet.http.HttpSession; +import java.util.ArrayList; +import java.util.List; + /** *

LessonMenuService class.

* @@ -62,7 +63,7 @@ public class LessonMenuService extends BaseService { * @param session a {@link javax.servlet.http.HttpSession} object. * @return a {@link java.util.List} object. */ - @RequestMapping(value = "/lessonmenu.mvc", produces = "application/json") + @RequestMapping(path = "/lessonmenu.mvc", produces = "application/json") public @ResponseBody List showLeftNav(HttpSession session) { List menu = new ArrayList(); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonPlanService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonPlanService.java index 6a35a45b5..6d1be3ade 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonPlanService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonPlanService.java @@ -53,7 +53,7 @@ public class LessonPlanService extends BaseService { * @param session a {@link javax.servlet.http.HttpSession} object. * @return a {@link java.lang.String} object. */ - @RequestMapping(value = "/lessonplan.mvc", produces = "application/html") + @RequestMapping(path = "/lessonplan.mvc", produces = "application/html") public @ResponseBody String showPlan(HttpSession session) { WebSession ws = getWebSession(session); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonTitleService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonTitleService.java index 3c58a0efc..1b9c9022f 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonTitleService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonTitleService.java @@ -24,7 +24,7 @@ public class LessonTitleService extends BaseService { * @param session a {@link javax.servlet.http.HttpSession} object. * @return a {@link java.lang.String} object. */ - @RequestMapping(value = "/lessontitle.mvc", produces = "application/html") + @RequestMapping(path = "/lessontitle.mvc", produces = "application/html") public @ResponseBody String showPlan(HttpSession session) { WebSession ws = getWebSession(session); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/ParameterService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/ParameterService.java index e7ebc9c39..47006d76f 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/ParameterService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/ParameterService.java @@ -58,7 +58,7 @@ public class ParameterService extends BaseService { * @param session a {@link javax.servlet.http.HttpSession} object. * @return a {@link java.util.List} object. */ - @RequestMapping(value = "/parameter.mvc", produces = "application/json") + @RequestMapping(path = "/parameter.mvc", produces = "application/json") public @ResponseBody List showParameters(HttpSession session) { WebSession ws = getWebSession(session); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/PluginReloadService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/PluginReloadService.java index 6355318aa..b1643b157 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/PluginReloadService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/PluginReloadService.java @@ -63,7 +63,7 @@ public class PluginReloadService extends BaseService { * @param session a {@link javax.servlet.http.HttpSession} object. * @return a {@link org.springframework.http.ResponseEntity} object. */ - @RequestMapping(value = "/reloadplugins.mvc", produces = MediaType.APPLICATION_JSON_VALUE) + @RequestMapping(path = "/reloadplugins.mvc", produces = MediaType.APPLICATION_JSON_VALUE) public @ResponseBody ResponseEntity> reloadPlugins(HttpSession session) { WebSession webSession = (WebSession) session.getAttribute(WebSession.SESSION); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/RestartLessonService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/RestartLessonService.java index d21f63dcd..7d6679cb6 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/RestartLessonService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/RestartLessonService.java @@ -47,7 +47,7 @@ public class RestartLessonService extends BaseService { * @param session a {@link javax.servlet.http.HttpSession} object. * @return a {@link java.lang.String} object. */ - @RequestMapping(value = "/restartlesson.mvc", produces = "text/text") + @RequestMapping(path = "/restartlesson.mvc", produces = "text/text") public @ResponseBody String restartLesson(HttpSession session) { WebSession ws = getWebSession(session); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/SessionService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/SessionService.java index caec4f34d..f86d06ed9 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/SessionService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/SessionService.java @@ -32,7 +32,7 @@ public class SessionService extends BaseService { * @param request a {@link javax.servlet.http.HttpServletRequest} object. * @return a {@link java.lang.String} object. */ - @RequestMapping(value = "/session.mvc", produces = "application/json") + @RequestMapping(path = "/session.mvc", produces = "application/json") public @ResponseBody String showSession(HttpServletRequest request, HttpSession session) { StringBuilder sb = new StringBuilder(); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/SolutionService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/SolutionService.java index b91d153b4..3cf245f42 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/SolutionService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/SolutionService.java @@ -53,7 +53,7 @@ public class SolutionService extends BaseService { * @param session a {@link javax.servlet.http.HttpSession} object. * @return a {@link java.lang.String} object. */ - @RequestMapping(value = "/solution.mvc", produces = "text/html") + @RequestMapping(path = "/solution.mvc", produces = "text/html") public @ResponseBody String showSolution(HttpSession session) { WebSession ws = getWebSession(session); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/SourceService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/SourceService.java index 059eeb470..da8edd2ff 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/SourceService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/SourceService.java @@ -57,7 +57,7 @@ public class SourceService extends BaseService { * @param session a {@link javax.servlet.http.HttpSession} object. * @return a {@link java.lang.String} object. */ - @RequestMapping(value = "/source.mvc", produces = "application/text") + @RequestMapping(path = "/source.mvc", produces = "application/text") public @ResponseBody String showSource(HttpSession session) { WebSession ws = getWebSession(session); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/session/Course.java b/webgoat-container/src/main/java/org/owasp/webgoat/session/Course.java index 2e27378d0..0a23f9fab 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/session/Course.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/session/Course.java @@ -3,10 +3,13 @@ package org.owasp.webgoat.session; import org.owasp.webgoat.HammerHead; import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Category; +import org.owasp.webgoat.plugins.LegacyLoader; import org.owasp.webgoat.plugins.Plugin; import org.owasp.webgoat.plugins.PluginsLoader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; import javax.servlet.ServletContext; import java.io.File; @@ -18,16 +21,6 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; -import javax.servlet.ServletContext; - -import org.owasp.webgoat.HammerHead; -import org.owasp.webgoat.lessons.AbstractLesson; -import org.owasp.webgoat.lessons.Category; -import org.owasp.webgoat.plugins.LegacyLoader; -import org.owasp.webgoat.plugins.Plugin; -import org.owasp.webgoat.plugins.PluginsLoader; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** ************************************************************************************************* @@ -63,7 +56,7 @@ public class Course { final Logger logger = LoggerFactory.getLogger(Course.class); - private final List lessons = new LinkedList(); + private List lessons = new LinkedList(); private final static String PROPERTIES_FILENAME = HammerHead.propertiesPath; @@ -262,7 +255,7 @@ public class Course { * Gets the lessons attribute of the Course object * * @param category Description of the Parameter - * @param role Description of the Parameter + * @param roles Description of the Parameter * @return The lessons value */ private List getLessons(Category category, List roles) { @@ -322,15 +315,30 @@ public class Course { return null; } + public void setLessons(List lessons) { + this.lessons = lessons; + } + /** *

loadLessonFromPlugin.

* * @param context a {@link javax.servlet.ServletContext} object. */ public void loadLessonFromPlugin(ServletContext context) { + Resource resource = new ClassPathResource("/plugin_lessons/plugin_lessons_marker.txt"); + String pluginPath = null; + String targetPath = null; + try { + pluginPath = resource.getFile().getParent(); + targetPath = pluginPath; + + } catch (IOException e) { + e.printStackTrace(); + } + logger.debug("Loading plugins into cache"); - String pluginPath = context.getRealPath("plugin_lessons"); - String targetPath = context.getRealPath("plugin_extracted"); + //String pluginPath = context.getRealPath("plugin_lessons"); + //String targetPath = context.getRealPath("plugin_extracted"); if (pluginPath == null) { logger.error("Plugins directory {} not found", pluginPath); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/session/WebgoatProperties.java b/webgoat-container/src/main/java/org/owasp/webgoat/session/WebgoatProperties.java index 4ba24d72a..395ccb40a 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/session/WebgoatProperties.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/session/WebgoatProperties.java @@ -2,9 +2,9 @@ package org.owasp.webgoat.session; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; -import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; @@ -57,12 +57,14 @@ public class WebgoatProperties extends Properties { if (propertiesFileName == null) { throw new IOException("Path to webgoat.properties is null, initialization must have failed"); } - File propertiesFile = new File(propertiesFileName); - if (propertiesFile.exists() == false) { - throw new IOException("Unable to locate webgoat.properties at: " + propertiesFileName); - } - FileInputStream in = new FileInputStream(propertiesFile); - load(in); + +// File propertiesFile = new File(propertiesFileName); +// if (propertiesFile.exists() == false) { +// throw new IOException("Unable to locate webgoat.properties at: " + propertiesFileName); +// } + Resource resource = new ClassPathResource("/webgoat.properties"); + //FileInputStream in = new FileInputStream(propertiesFile); + load(resource.getInputStream()); } /** diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/util/LabelProvider.java b/webgoat-container/src/main/java/org/owasp/webgoat/util/LabelProvider.java index 674699c01..05fb9c4f2 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/util/LabelProvider.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/util/LabelProvider.java @@ -7,7 +7,6 @@ import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.UrlResource; import org.springframework.stereotype.Component; -import javax.inject.Singleton; import java.net.MalformedURLException; import java.nio.file.Path; import java.util.Arrays; @@ -47,7 +46,6 @@ import java.util.Locale; * @author dm */ @Component -@Singleton public class LabelProvider { /** Constant DEFAULT_LANGUAGE="Locale.ENGLISH.getLanguage()" */ public final static String DEFAULT_LANGUAGE = Locale.ENGLISH.getLanguage(); diff --git a/webgoat-container/src/main/resources/application.properties b/webgoat-container/src/main/resources/application.properties new file mode 100644 index 000000000..10ba0d867 --- /dev/null +++ b/webgoat-container/src/main/resources/application.properties @@ -0,0 +1,11 @@ +#spring.mvc.view.prefix=/WEB-INF/jsp/ +#spring.mvc.view.suffix=.jsp +#server.servlet-path=/* +#server.jsp-servlet.class-name=org.apache.jasper.servlet.JspServlet +#server.jsp-servlet.registered=true + +server.error.include-stacktrace=always +logging.level.org.springframework=DEBUG +logging.level.org.hibernate=ERROR +spring.thymeleaf.cache=false +security.enable-csrf=false \ No newline at end of file diff --git a/webgoat-container/src/main/resources/plugin_lessons/plugin_lessons_marker.txt b/webgoat-container/src/main/resources/plugin_lessons/plugin_lessons_marker.txt new file mode 100644 index 000000000..e69de29bb diff --git a/webgoat-container/src/main/webapp/css/animate.css b/webgoat-container/src/main/resources/static/css/animate.css similarity index 95% rename from webgoat-container/src/main/webapp/css/animate.css rename to webgoat-container/src/main/resources/static/css/animate.css index 97f28788e..d71da17ae 100644 --- a/webgoat-container/src/main/webapp/css/animate.css +++ b/webgoat-container/src/main/resources/static/css/animate.css @@ -1,2744 +1,2744 @@ -@charset "UTF-8"; - - -/*! -Animate.css - http://daneden.me/animate -Licensed under the MIT license - -Copyright (c) 2013 Daniel Eden - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -.animated { - -webkit-animation-duration: 1s; - animation-duration: 1s; - -webkit-animation-fill-mode: both; - animation-fill-mode: both; -} - -.animated.hinge { - -webkit-animation-duration: 2s; - animation-duration: 2s; -} - -@-webkit-keyframes bounce { - 0%, 20%, 50%, 80%, 100% { - -webkit-transform: translateY(0); - transform: translateY(0); - } - - 40% { - -webkit-transform: translateY(-30px); - transform: translateY(-30px); - } - - 60% { - -webkit-transform: translateY(-15px); - transform: translateY(-15px); - } -} - -@keyframes bounce { - 0%, 20%, 50%, 80%, 100% { - -webkit-transform: translateY(0); - -ms-transform: translateY(0); - transform: translateY(0); - } - - 40% { - -webkit-transform: translateY(-30px); - -ms-transform: translateY(-30px); - transform: translateY(-30px); - } - - 60% { - -webkit-transform: translateY(-15px); - -ms-transform: translateY(-15px); - transform: translateY(-15px); - } -} - -.bounce { - -webkit-animation-name: bounce; - animation-name: bounce; -} - -@-webkit-keyframes flash { - 0%, 50%, 100% { - opacity: 1; - } - - 25%, 75% { - opacity: 0; - } -} - -@keyframes flash { - 0%, 50%, 100% { - opacity: 1; - } - - 25%, 75% { - opacity: 0; - } -} - -.flash { - -webkit-animation-name: flash; - animation-name: flash; -} - -/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ - -@-webkit-keyframes pulse { - 0% { - -webkit-transform: scale(1); - transform: scale(1); - } - - 50% { - -webkit-transform: scale(1.1); - transform: scale(1.1); - } - - 100% { - -webkit-transform: scale(1); - transform: scale(1); - } -} - -@keyframes pulse { - 0% { - -webkit-transform: scale(1); - -ms-transform: scale(1); - transform: scale(1); - } - - 50% { - -webkit-transform: scale(1.1); - -ms-transform: scale(1.1); - transform: scale(1.1); - } - - 100% { - -webkit-transform: scale(1); - -ms-transform: scale(1); - transform: scale(1); - } -} - -.pulse { - -webkit-animation-name: pulse; - animation-name: pulse; -} - -@-webkit-keyframes shake { - 0%, 100% { - -webkit-transform: translateX(0); - transform: translateX(0); - } - - 10%, 30%, 50%, 70%, 90% { - -webkit-transform: translateX(-10px); - transform: translateX(-10px); - } - - 20%, 40%, 60%, 80% { - -webkit-transform: translateX(10px); - transform: translateX(10px); - } -} - -@keyframes shake { - 0%, 100% { - -webkit-transform: translateX(0); - -ms-transform: translateX(0); - transform: translateX(0); - } - - 10%, 30%, 50%, 70%, 90% { - -webkit-transform: translateX(-10px); - -ms-transform: translateX(-10px); - transform: translateX(-10px); - } - - 20%, 40%, 60%, 80% { - -webkit-transform: translateX(10px); - -ms-transform: translateX(10px); - transform: translateX(10px); - } -} - -.shake { - -webkit-animation-name: shake; - animation-name: shake; -} - -@-webkit-keyframes swing { - 20% { - -webkit-transform: rotate(15deg); - transform: rotate(15deg); - } - - 40% { - -webkit-transform: rotate(-10deg); - transform: rotate(-10deg); - } - - 60% { - -webkit-transform: rotate(5deg); - transform: rotate(5deg); - } - - 80% { - -webkit-transform: rotate(-5deg); - transform: rotate(-5deg); - } - - 100% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } -} - -@keyframes swing { - 20% { - -webkit-transform: rotate(15deg); - -ms-transform: rotate(15deg); - transform: rotate(15deg); - } - - 40% { - -webkit-transform: rotate(-10deg); - -ms-transform: rotate(-10deg); - transform: rotate(-10deg); - } - - 60% { - -webkit-transform: rotate(5deg); - -ms-transform: rotate(5deg); - transform: rotate(5deg); - } - - 80% { - -webkit-transform: rotate(-5deg); - -ms-transform: rotate(-5deg); - transform: rotate(-5deg); - } - - 100% { - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); - } -} - -.swing { - -webkit-transform-origin: top center; - -ms-transform-origin: top center; - transform-origin: top center; - -webkit-animation-name: swing; - animation-name: swing; -} - -@-webkit-keyframes tada { - 0% { - -webkit-transform: scale(1); - transform: scale(1); - } - - 10%, 20% { - -webkit-transform: scale(0.9) rotate(-3deg); - transform: scale(0.9) rotate(-3deg); - } - - 30%, 50%, 70%, 90% { - -webkit-transform: scale(1.1) rotate(3deg); - transform: scale(1.1) rotate(3deg); - } - - 40%, 60%, 80% { - -webkit-transform: scale(1.1) rotate(-3deg); - transform: scale(1.1) rotate(-3deg); - } - - 100% { - -webkit-transform: scale(1) rotate(0); - transform: scale(1) rotate(0); - } -} - -@keyframes tada { - 0% { - -webkit-transform: scale(1); - -ms-transform: scale(1); - transform: scale(1); - } - - 10%, 20% { - -webkit-transform: scale(0.9) rotate(-3deg); - -ms-transform: scale(0.9) rotate(-3deg); - transform: scale(0.9) rotate(-3deg); - } - - 30%, 50%, 70%, 90% { - -webkit-transform: scale(1.1) rotate(3deg); - -ms-transform: scale(1.1) rotate(3deg); - transform: scale(1.1) rotate(3deg); - } - - 40%, 60%, 80% { - -webkit-transform: scale(1.1) rotate(-3deg); - -ms-transform: scale(1.1) rotate(-3deg); - transform: scale(1.1) rotate(-3deg); - } - - 100% { - -webkit-transform: scale(1) rotate(0); - -ms-transform: scale(1) rotate(0); - transform: scale(1) rotate(0); - } -} - -.tada { - -webkit-animation-name: tada; - animation-name: tada; -} - -/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ - -@-webkit-keyframes wobble { - 0% { - -webkit-transform: translateX(0%); - transform: translateX(0%); - } - - 15% { - -webkit-transform: translateX(-25%) rotate(-5deg); - transform: translateX(-25%) rotate(-5deg); - } - - 30% { - -webkit-transform: translateX(20%) rotate(3deg); - transform: translateX(20%) rotate(3deg); - } - - 45% { - -webkit-transform: translateX(-15%) rotate(-3deg); - transform: translateX(-15%) rotate(-3deg); - } - - 60% { - -webkit-transform: translateX(10%) rotate(2deg); - transform: translateX(10%) rotate(2deg); - } - - 75% { - -webkit-transform: translateX(-5%) rotate(-1deg); - transform: translateX(-5%) rotate(-1deg); - } - - 100% { - -webkit-transform: translateX(0%); - transform: translateX(0%); - } -} - -@keyframes wobble { - 0% { - -webkit-transform: translateX(0%); - -ms-transform: translateX(0%); - transform: translateX(0%); - } - - 15% { - -webkit-transform: translateX(-25%) rotate(-5deg); - -ms-transform: translateX(-25%) rotate(-5deg); - transform: translateX(-25%) rotate(-5deg); - } - - 30% { - -webkit-transform: translateX(20%) rotate(3deg); - -ms-transform: translateX(20%) rotate(3deg); - transform: translateX(20%) rotate(3deg); - } - - 45% { - -webkit-transform: translateX(-15%) rotate(-3deg); - -ms-transform: translateX(-15%) rotate(-3deg); - transform: translateX(-15%) rotate(-3deg); - } - - 60% { - -webkit-transform: translateX(10%) rotate(2deg); - -ms-transform: translateX(10%) rotate(2deg); - transform: translateX(10%) rotate(2deg); - } - - 75% { - -webkit-transform: translateX(-5%) rotate(-1deg); - -ms-transform: translateX(-5%) rotate(-1deg); - transform: translateX(-5%) rotate(-1deg); - } - - 100% { - -webkit-transform: translateX(0%); - -ms-transform: translateX(0%); - transform: translateX(0%); - } -} - -.wobble { - -webkit-animation-name: wobble; - animation-name: wobble; -} - -@-webkit-keyframes bounceIn { - 0% { - opacity: 0; - -webkit-transform: scale(.3); - transform: scale(.3); - } - - 50% { - opacity: 1; - -webkit-transform: scale(1.05); - transform: scale(1.05); - } - - 70% { - -webkit-transform: scale(.9); - transform: scale(.9); - } - - 100% { - -webkit-transform: scale(1); - transform: scale(1); - } -} - -@keyframes bounceIn { - 0% { - opacity: 0; - -webkit-transform: scale(.3); - -ms-transform: scale(.3); - transform: scale(.3); - } - - 50% { - opacity: 1; - -webkit-transform: scale(1.05); - -ms-transform: scale(1.05); - transform: scale(1.05); - } - - 70% { - -webkit-transform: scale(.9); - -ms-transform: scale(.9); - transform: scale(.9); - } - - 100% { - -webkit-transform: scale(1); - -ms-transform: scale(1); - transform: scale(1); - } -} - -.bounceIn { - -webkit-animation-name: bounceIn; - animation-name: bounceIn; -} - -@-webkit-keyframes bounceInDown { - 0% { - opacity: 0; - -webkit-transform: translateY(-2000px); - transform: translateY(-2000px); - } - - 60% { - opacity: 1; - -webkit-transform: translateY(30px); - transform: translateY(30px); - } - - 80% { - -webkit-transform: translateY(-10px); - transform: translateY(-10px); - } - - 100% { - -webkit-transform: translateY(0); - transform: translateY(0); - } -} - -@keyframes bounceInDown { - 0% { - opacity: 0; - -webkit-transform: translateY(-2000px); - -ms-transform: translateY(-2000px); - transform: translateY(-2000px); - } - - 60% { - opacity: 1; - -webkit-transform: translateY(30px); - -ms-transform: translateY(30px); - transform: translateY(30px); - } - - 80% { - -webkit-transform: translateY(-10px); - -ms-transform: translateY(-10px); - transform: translateY(-10px); - } - - 100% { - -webkit-transform: translateY(0); - -ms-transform: translateY(0); - transform: translateY(0); - } -} - -.bounceInDown { - -webkit-animation-name: bounceInDown; - animation-name: bounceInDown; -} - -@-webkit-keyframes bounceInLeft { - 0% { - opacity: 0; - -webkit-transform: translateX(-2000px); - transform: translateX(-2000px); - } - - 60% { - opacity: 1; - -webkit-transform: translateX(30px); - transform: translateX(30px); - } - - 80% { - -webkit-transform: translateX(-10px); - transform: translateX(-10px); - } - - 100% { - -webkit-transform: translateX(0); - transform: translateX(0); - } -} - -@keyframes bounceInLeft { - 0% { - opacity: 0; - -webkit-transform: translateX(-2000px); - -ms-transform: translateX(-2000px); - transform: translateX(-2000px); - } - - 60% { - opacity: 1; - -webkit-transform: translateX(30px); - -ms-transform: translateX(30px); - transform: translateX(30px); - } - - 80% { - -webkit-transform: translateX(-10px); - -ms-transform: translateX(-10px); - transform: translateX(-10px); - } - - 100% { - -webkit-transform: translateX(0); - -ms-transform: translateX(0); - transform: translateX(0); - } -} - -.bounceInLeft { - -webkit-animation-name: bounceInLeft; - animation-name: bounceInLeft; -} - -@-webkit-keyframes bounceInRight { - 0% { - opacity: 0; - -webkit-transform: translateX(2000px); - transform: translateX(2000px); - } - - 60% { - opacity: 1; - -webkit-transform: translateX(-30px); - transform: translateX(-30px); - } - - 80% { - -webkit-transform: translateX(10px); - transform: translateX(10px); - } - - 100% { - -webkit-transform: translateX(0); - transform: translateX(0); - } -} - -@keyframes bounceInRight { - 0% { - opacity: 0; - -webkit-transform: translateX(2000px); - -ms-transform: translateX(2000px); - transform: translateX(2000px); - } - - 60% { - opacity: 1; - -webkit-transform: translateX(-30px); - -ms-transform: translateX(-30px); - transform: translateX(-30px); - } - - 80% { - -webkit-transform: translateX(10px); - -ms-transform: translateX(10px); - transform: translateX(10px); - } - - 100% { - -webkit-transform: translateX(0); - -ms-transform: translateX(0); - transform: translateX(0); - } -} - -.bounceInRight { - -webkit-animation-name: bounceInRight; - animation-name: bounceInRight; -} - -@-webkit-keyframes bounceInUp { - 0% { - opacity: 0; - -webkit-transform: translateY(2000px); - transform: translateY(2000px); - } - - 60% { - opacity: 1; - -webkit-transform: translateY(-30px); - transform: translateY(-30px); - } - - 80% { - -webkit-transform: translateY(10px); - transform: translateY(10px); - } - - 100% { - -webkit-transform: translateY(0); - transform: translateY(0); - } -} - -@keyframes bounceInUp { - 0% { - opacity: 0; - -webkit-transform: translateY(2000px); - -ms-transform: translateY(2000px); - transform: translateY(2000px); - } - - 60% { - opacity: 1; - -webkit-transform: translateY(-30px); - -ms-transform: translateY(-30px); - transform: translateY(-30px); - } - - 80% { - -webkit-transform: translateY(10px); - -ms-transform: translateY(10px); - transform: translateY(10px); - } - - 100% { - -webkit-transform: translateY(0); - -ms-transform: translateY(0); - transform: translateY(0); - } -} - -.bounceInUp { - -webkit-animation-name: bounceInUp; - animation-name: bounceInUp; -} - -@-webkit-keyframes bounceOut { - 0% { - -webkit-transform: scale(1); - transform: scale(1); - } - - 25% { - -webkit-transform: scale(.95); - transform: scale(.95); - } - - 50% { - opacity: 1; - -webkit-transform: scale(1.1); - transform: scale(1.1); - } - - 100% { - opacity: 0; - -webkit-transform: scale(.3); - transform: scale(.3); - } -} - -@keyframes bounceOut { - 0% { - -webkit-transform: scale(1); - -ms-transform: scale(1); - transform: scale(1); - } - - 25% { - -webkit-transform: scale(.95); - -ms-transform: scale(.95); - transform: scale(.95); - } - - 50% { - opacity: 1; - -webkit-transform: scale(1.1); - -ms-transform: scale(1.1); - transform: scale(1.1); - } - - 100% { - opacity: 0; - -webkit-transform: scale(.3); - -ms-transform: scale(.3); - transform: scale(.3); - } -} - -.bounceOut { - -webkit-animation-name: bounceOut; - animation-name: bounceOut; -} - -@-webkit-keyframes bounceOutDown { - 0% { - -webkit-transform: translateY(0); - transform: translateY(0); - } - - 20% { - opacity: 1; - -webkit-transform: translateY(-20px); - transform: translateY(-20px); - } - - 100% { - opacity: 0; - -webkit-transform: translateY(2000px); - transform: translateY(2000px); - } -} - -@keyframes bounceOutDown { - 0% { - -webkit-transform: translateY(0); - -ms-transform: translateY(0); - transform: translateY(0); - } - - 20% { - opacity: 1; - -webkit-transform: translateY(-20px); - -ms-transform: translateY(-20px); - transform: translateY(-20px); - } - - 100% { - opacity: 0; - -webkit-transform: translateY(2000px); - -ms-transform: translateY(2000px); - transform: translateY(2000px); - } -} - -.bounceOutDown { - -webkit-animation-name: bounceOutDown; - animation-name: bounceOutDown; -} - -@-webkit-keyframes bounceOutLeft { - 0% { - -webkit-transform: translateX(0); - transform: translateX(0); - } - - 20% { - opacity: 1; - -webkit-transform: translateX(20px); - transform: translateX(20px); - } - - 100% { - opacity: 0; - -webkit-transform: translateX(-2000px); - transform: translateX(-2000px); - } -} - -@keyframes bounceOutLeft { - 0% { - -webkit-transform: translateX(0); - -ms-transform: translateX(0); - transform: translateX(0); - } - - 20% { - opacity: 1; - -webkit-transform: translateX(20px); - -ms-transform: translateX(20px); - transform: translateX(20px); - } - - 100% { - opacity: 0; - -webkit-transform: translateX(-2000px); - -ms-transform: translateX(-2000px); - transform: translateX(-2000px); - } -} - -.bounceOutLeft { - -webkit-animation-name: bounceOutLeft; - animation-name: bounceOutLeft; -} - -@-webkit-keyframes bounceOutRight { - 0% { - -webkit-transform: translateX(0); - transform: translateX(0); - } - - 20% { - opacity: 1; - -webkit-transform: translateX(-20px); - transform: translateX(-20px); - } - - 100% { - opacity: 0; - -webkit-transform: translateX(2000px); - transform: translateX(2000px); - } -} - -@keyframes bounceOutRight { - 0% { - -webkit-transform: translateX(0); - -ms-transform: translateX(0); - transform: translateX(0); - } - - 20% { - opacity: 1; - -webkit-transform: translateX(-20px); - -ms-transform: translateX(-20px); - transform: translateX(-20px); - } - - 100% { - opacity: 0; - -webkit-transform: translateX(2000px); - -ms-transform: translateX(2000px); - transform: translateX(2000px); - } -} - -.bounceOutRight { - -webkit-animation-name: bounceOutRight; - animation-name: bounceOutRight; -} - -@-webkit-keyframes bounceOutUp { - 0% { - -webkit-transform: translateY(0); - transform: translateY(0); - } - - 20% { - opacity: 1; - -webkit-transform: translateY(20px); - transform: translateY(20px); - } - - 100% { - opacity: 0; - -webkit-transform: translateY(-2000px); - transform: translateY(-2000px); - } -} - -@keyframes bounceOutUp { - 0% { - -webkit-transform: translateY(0); - -ms-transform: translateY(0); - transform: translateY(0); - } - - 20% { - opacity: 1; - -webkit-transform: translateY(20px); - -ms-transform: translateY(20px); - transform: translateY(20px); - } - - 100% { - opacity: 0; - -webkit-transform: translateY(-2000px); - -ms-transform: translateY(-2000px); - transform: translateY(-2000px); - } -} - -.bounceOutUp { - -webkit-animation-name: bounceOutUp; - animation-name: bounceOutUp; -} - -@-webkit-keyframes fadeIn { - 0% { - opacity: 0; - } - - 100% { - opacity: 1; - } -} - -@keyframes fadeIn { - 0% { - opacity: 0; - } - - 100% { - opacity: 1; - } -} - -.fadeIn { - -webkit-animation-name: fadeIn; - animation-name: fadeIn; -} - -@-webkit-keyframes fadeInDown { - 0% { - opacity: 0; - -webkit-transform: translateY(-20px); - transform: translateY(-20px); - } - - 100% { - opacity: 1; - -webkit-transform: translateY(0); - transform: translateY(0); - } -} - -@keyframes fadeInDown { - 0% { - opacity: 0; - -webkit-transform: translateY(-20px); - -ms-transform: translateY(-20px); - transform: translateY(-20px); - } - - 100% { - opacity: 1; - -webkit-transform: translateY(0); - -ms-transform: translateY(0); - transform: translateY(0); - } -} - -.fadeInDown { - -webkit-animation-name: fadeInDown; - animation-name: fadeInDown; -} - -@-webkit-keyframes fadeInDownBig { - 0% { - opacity: 0; - -webkit-transform: translateY(-2000px); - transform: translateY(-2000px); - } - - 100% { - opacity: 1; - -webkit-transform: translateY(0); - transform: translateY(0); - } -} - -@keyframes fadeInDownBig { - 0% { - opacity: 0; - -webkit-transform: translateY(-2000px); - -ms-transform: translateY(-2000px); - transform: translateY(-2000px); - } - - 100% { - opacity: 1; - -webkit-transform: translateY(0); - -ms-transform: translateY(0); - transform: translateY(0); - } -} - -.fadeInDownBig { - -webkit-animation-name: fadeInDownBig; - animation-name: fadeInDownBig; -} - -@-webkit-keyframes fadeInLeft { - 0% { - opacity: 0; - -webkit-transform: translateX(-20px); - transform: translateX(-20px); - } - - 100% { - opacity: 1; - -webkit-transform: translateX(0); - transform: translateX(0); - } -} - -@keyframes fadeInLeft { - 0% { - opacity: 0; - -webkit-transform: translateX(-20px); - -ms-transform: translateX(-20px); - transform: translateX(-20px); - } - - 100% { - opacity: 1; - -webkit-transform: translateX(0); - -ms-transform: translateX(0); - transform: translateX(0); - } -} - -.fadeInLeft { - -webkit-animation-name: fadeInLeft; - animation-name: fadeInLeft; -} - -@-webkit-keyframes fadeInLeftBig { - 0% { - opacity: 0; - -webkit-transform: translateX(-2000px); - transform: translateX(-2000px); - } - - 100% { - opacity: 1; - -webkit-transform: translateX(0); - transform: translateX(0); - } -} - -@keyframes fadeInLeftBig { - 0% { - opacity: 0; - -webkit-transform: translateX(-2000px); - -ms-transform: translateX(-2000px); - transform: translateX(-2000px); - } - - 100% { - opacity: 1; - -webkit-transform: translateX(0); - -ms-transform: translateX(0); - transform: translateX(0); - } -} - -.fadeInLeftBig { - -webkit-animation-name: fadeInLeftBig; - animation-name: fadeInLeftBig; -} - -@-webkit-keyframes fadeInRight { - 0% { - opacity: 0; - -webkit-transform: translateX(20px); - transform: translateX(20px); - } - - 100% { - opacity: 1; - -webkit-transform: translateX(0); - transform: translateX(0); - } -} - -@keyframes fadeInRight { - 0% { - opacity: 0; - -webkit-transform: translateX(20px); - -ms-transform: translateX(20px); - transform: translateX(20px); - } - - 100% { - opacity: 1; - -webkit-transform: translateX(0); - -ms-transform: translateX(0); - transform: translateX(0); - } -} - -.fadeInRight { - -webkit-animation-name: fadeInRight; - animation-name: fadeInRight; -} - -@-webkit-keyframes fadeInRightBig { - 0% { - opacity: 0; - -webkit-transform: translateX(2000px); - transform: translateX(2000px); - } - - 100% { - opacity: 1; - -webkit-transform: translateX(0); - transform: translateX(0); - } -} - -@keyframes fadeInRightBig { - 0% { - opacity: 0; - -webkit-transform: translateX(2000px); - -ms-transform: translateX(2000px); - transform: translateX(2000px); - } - - 100% { - opacity: 1; - -webkit-transform: translateX(0); - -ms-transform: translateX(0); - transform: translateX(0); - } -} - -.fadeInRightBig { - -webkit-animation-name: fadeInRightBig; - animation-name: fadeInRightBig; -} - -@-webkit-keyframes fadeInUp { - 0% { - opacity: 0; - -webkit-transform: translateY(20px); - transform: translateY(20px); - } - - 100% { - opacity: 1; - -webkit-transform: translateY(0); - transform: translateY(0); - } -} - -@keyframes fadeInUp { - 0% { - opacity: 0; - -webkit-transform: translateY(20px); - -ms-transform: translateY(20px); - transform: translateY(20px); - } - - 100% { - opacity: 1; - -webkit-transform: translateY(0); - -ms-transform: translateY(0); - transform: translateY(0); - } -} - -.fadeInUp { - -webkit-animation-name: fadeInUp; - animation-name: fadeInUp; -} - -@-webkit-keyframes fadeInUpBig { - 0% { - opacity: 0; - -webkit-transform: translateY(2000px); - transform: translateY(2000px); - } - - 100% { - opacity: 1; - -webkit-transform: translateY(0); - transform: translateY(0); - } -} - -@keyframes fadeInUpBig { - 0% { - opacity: 0; - -webkit-transform: translateY(2000px); - -ms-transform: translateY(2000px); - transform: translateY(2000px); - } - - 100% { - opacity: 1; - -webkit-transform: translateY(0); - -ms-transform: translateY(0); - transform: translateY(0); - } -} - -.fadeInUpBig { - -webkit-animation-name: fadeInUpBig; - animation-name: fadeInUpBig; -} - -@-webkit-keyframes fadeOut { - 0% { - opacity: 1; - } - - 100% { - opacity: 0; - } -} - -@keyframes fadeOut { - 0% { - opacity: 1; - } - - 100% { - opacity: 0; - } -} - -.fadeOut { - -webkit-animation-name: fadeOut; - animation-name: fadeOut; -} - -@-webkit-keyframes fadeOutDown { - 0% { - opacity: 1; - -webkit-transform: translateY(0); - transform: translateY(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateY(20px); - transform: translateY(20px); - } -} - -@keyframes fadeOutDown { - 0% { - opacity: 1; - -webkit-transform: translateY(0); - -ms-transform: translateY(0); - transform: translateY(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateY(20px); - -ms-transform: translateY(20px); - transform: translateY(20px); - } -} - -.fadeOutDown { - -webkit-animation-name: fadeOutDown; - animation-name: fadeOutDown; -} - -@-webkit-keyframes fadeOutDownBig { - 0% { - opacity: 1; - -webkit-transform: translateY(0); - transform: translateY(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateY(2000px); - transform: translateY(2000px); - } -} - -@keyframes fadeOutDownBig { - 0% { - opacity: 1; - -webkit-transform: translateY(0); - -ms-transform: translateY(0); - transform: translateY(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateY(2000px); - -ms-transform: translateY(2000px); - transform: translateY(2000px); - } -} - -.fadeOutDownBig { - -webkit-animation-name: fadeOutDownBig; - animation-name: fadeOutDownBig; -} - -@-webkit-keyframes fadeOutLeft { - 0% { - opacity: 1; - -webkit-transform: translateX(0); - transform: translateX(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateX(-20px); - transform: translateX(-20px); - } -} - -@keyframes fadeOutLeft { - 0% { - opacity: 1; - -webkit-transform: translateX(0); - -ms-transform: translateX(0); - transform: translateX(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateX(-20px); - -ms-transform: translateX(-20px); - transform: translateX(-20px); - } -} - -.fadeOutLeft { - -webkit-animation-name: fadeOutLeft; - animation-name: fadeOutLeft; -} - -@-webkit-keyframes fadeOutLeftBig { - 0% { - opacity: 1; - -webkit-transform: translateX(0); - transform: translateX(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateX(-2000px); - transform: translateX(-2000px); - } -} - -@keyframes fadeOutLeftBig { - 0% { - opacity: 1; - -webkit-transform: translateX(0); - -ms-transform: translateX(0); - transform: translateX(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateX(-2000px); - -ms-transform: translateX(-2000px); - transform: translateX(-2000px); - } -} - -.fadeOutLeftBig { - -webkit-animation-name: fadeOutLeftBig; - animation-name: fadeOutLeftBig; -} - -@-webkit-keyframes fadeOutRight { - 0% { - opacity: 1; - -webkit-transform: translateX(0); - transform: translateX(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateX(20px); - transform: translateX(20px); - } -} - -@keyframes fadeOutRight { - 0% { - opacity: 1; - -webkit-transform: translateX(0); - -ms-transform: translateX(0); - transform: translateX(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateX(20px); - -ms-transform: translateX(20px); - transform: translateX(20px); - } -} - -.fadeOutRight { - -webkit-animation-name: fadeOutRight; - animation-name: fadeOutRight; -} - -@-webkit-keyframes fadeOutRightBig { - 0% { - opacity: 1; - -webkit-transform: translateX(0); - transform: translateX(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateX(2000px); - transform: translateX(2000px); - } -} - -@keyframes fadeOutRightBig { - 0% { - opacity: 1; - -webkit-transform: translateX(0); - -ms-transform: translateX(0); - transform: translateX(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateX(2000px); - -ms-transform: translateX(2000px); - transform: translateX(2000px); - } -} - -.fadeOutRightBig { - -webkit-animation-name: fadeOutRightBig; - animation-name: fadeOutRightBig; -} - -@-webkit-keyframes fadeOutUp { - 0% { - opacity: 1; - -webkit-transform: translateY(0); - transform: translateY(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateY(-20px); - transform: translateY(-20px); - } -} - -@keyframes fadeOutUp { - 0% { - opacity: 1; - -webkit-transform: translateY(0); - -ms-transform: translateY(0); - transform: translateY(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateY(-20px); - -ms-transform: translateY(-20px); - transform: translateY(-20px); - } -} - -.fadeOutUp { - -webkit-animation-name: fadeOutUp; - animation-name: fadeOutUp; -} - -@-webkit-keyframes fadeOutUpBig { - 0% { - opacity: 1; - -webkit-transform: translateY(0); - transform: translateY(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateY(-2000px); - transform: translateY(-2000px); - } -} - -@keyframes fadeOutUpBig { - 0% { - opacity: 1; - -webkit-transform: translateY(0); - -ms-transform: translateY(0); - transform: translateY(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateY(-2000px); - -ms-transform: translateY(-2000px); - transform: translateY(-2000px); - } -} - -.fadeOutUpBig { - -webkit-animation-name: fadeOutUpBig; - animation-name: fadeOutUpBig; -} - -@-webkit-keyframes flip { - 0% { - -webkit-transform: perspective(400px) translateZ(0) rotateY(0) scale(1); - transform: perspective(400px) translateZ(0) rotateY(0) scale(1); - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; - } - - 40% { - -webkit-transform: perspective(400px) translateZ(150px) rotateY(170deg) scale(1); - transform: perspective(400px) translateZ(150px) rotateY(170deg) scale(1); - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; - } - - 50% { - -webkit-transform: perspective(400px) translateZ(150px) rotateY(190deg) scale(1); - transform: perspective(400px) translateZ(150px) rotateY(190deg) scale(1); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 80% { - -webkit-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(.95); - transform: perspective(400px) translateZ(0) rotateY(360deg) scale(.95); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 100% { - -webkit-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(1); - transform: perspective(400px) translateZ(0) rotateY(360deg) scale(1); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } -} - -@keyframes flip { - 0% { - -webkit-transform: perspective(400px) translateZ(0) rotateY(0) scale(1); - -ms-transform: perspective(400px) translateZ(0) rotateY(0) scale(1); - transform: perspective(400px) translateZ(0) rotateY(0) scale(1); - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; - } - - 40% { - -webkit-transform: perspective(400px) translateZ(150px) rotateY(170deg) scale(1); - -ms-transform: perspective(400px) translateZ(150px) rotateY(170deg) scale(1); - transform: perspective(400px) translateZ(150px) rotateY(170deg) scale(1); - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; - } - - 50% { - -webkit-transform: perspective(400px) translateZ(150px) rotateY(190deg) scale(1); - -ms-transform: perspective(400px) translateZ(150px) rotateY(190deg) scale(1); - transform: perspective(400px) translateZ(150px) rotateY(190deg) scale(1); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 80% { - -webkit-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(.95); - -ms-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(.95); - transform: perspective(400px) translateZ(0) rotateY(360deg) scale(.95); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 100% { - -webkit-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(1); - -ms-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(1); - transform: perspective(400px) translateZ(0) rotateY(360deg) scale(1); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } -} - -.animated.flip { - -webkit-backface-visibility: visible; - -ms-backface-visibility: visible; - backface-visibility: visible; - -webkit-animation-name: flip; - animation-name: flip; -} - -@-webkit-keyframes flipInX { - 0% { - -webkit-transform: perspective(400px) rotateX(90deg); - transform: perspective(400px) rotateX(90deg); - opacity: 0; - } - - 40% { - -webkit-transform: perspective(400px) rotateX(-10deg); - transform: perspective(400px) rotateX(-10deg); - } - - 70% { - -webkit-transform: perspective(400px) rotateX(10deg); - transform: perspective(400px) rotateX(10deg); - } - - 100% { - -webkit-transform: perspective(400px) rotateX(0deg); - transform: perspective(400px) rotateX(0deg); - opacity: 1; - } -} - -@keyframes flipInX { - 0% { - -webkit-transform: perspective(400px) rotateX(90deg); - -ms-transform: perspective(400px) rotateX(90deg); - transform: perspective(400px) rotateX(90deg); - opacity: 0; - } - - 40% { - -webkit-transform: perspective(400px) rotateX(-10deg); - -ms-transform: perspective(400px) rotateX(-10deg); - transform: perspective(400px) rotateX(-10deg); - } - - 70% { - -webkit-transform: perspective(400px) rotateX(10deg); - -ms-transform: perspective(400px) rotateX(10deg); - transform: perspective(400px) rotateX(10deg); - } - - 100% { - -webkit-transform: perspective(400px) rotateX(0deg); - -ms-transform: perspective(400px) rotateX(0deg); - transform: perspective(400px) rotateX(0deg); - opacity: 1; - } -} - -.flipInX { - -webkit-backface-visibility: visible !important; - -ms-backface-visibility: visible !important; - backface-visibility: visible !important; - -webkit-animation-name: flipInX; - animation-name: flipInX; -} - -@-webkit-keyframes flipInY { - 0% { - -webkit-transform: perspective(400px) rotateY(90deg); - transform: perspective(400px) rotateY(90deg); - opacity: 0; - } - - 40% { - -webkit-transform: perspective(400px) rotateY(-10deg); - transform: perspective(400px) rotateY(-10deg); - } - - 70% { - -webkit-transform: perspective(400px) rotateY(10deg); - transform: perspective(400px) rotateY(10deg); - } - - 100% { - -webkit-transform: perspective(400px) rotateY(0deg); - transform: perspective(400px) rotateY(0deg); - opacity: 1; - } -} - -@keyframes flipInY { - 0% { - -webkit-transform: perspective(400px) rotateY(90deg); - -ms-transform: perspective(400px) rotateY(90deg); - transform: perspective(400px) rotateY(90deg); - opacity: 0; - } - - 40% { - -webkit-transform: perspective(400px) rotateY(-10deg); - -ms-transform: perspective(400px) rotateY(-10deg); - transform: perspective(400px) rotateY(-10deg); - } - - 70% { - -webkit-transform: perspective(400px) rotateY(10deg); - -ms-transform: perspective(400px) rotateY(10deg); - transform: perspective(400px) rotateY(10deg); - } - - 100% { - -webkit-transform: perspective(400px) rotateY(0deg); - -ms-transform: perspective(400px) rotateY(0deg); - transform: perspective(400px) rotateY(0deg); - opacity: 1; - } -} - -.flipInY { - -webkit-backface-visibility: visible !important; - -ms-backface-visibility: visible !important; - backface-visibility: visible !important; - -webkit-animation-name: flipInY; - animation-name: flipInY; -} - -@-webkit-keyframes flipOutX { - 0% { - -webkit-transform: perspective(400px) rotateX(0deg); - transform: perspective(400px) rotateX(0deg); - opacity: 1; - } - - 100% { - -webkit-transform: perspective(400px) rotateX(90deg); - transform: perspective(400px) rotateX(90deg); - opacity: 0; - } -} - -@keyframes flipOutX { - 0% { - -webkit-transform: perspective(400px) rotateX(0deg); - -ms-transform: perspective(400px) rotateX(0deg); - transform: perspective(400px) rotateX(0deg); - opacity: 1; - } - - 100% { - -webkit-transform: perspective(400px) rotateX(90deg); - -ms-transform: perspective(400px) rotateX(90deg); - transform: perspective(400px) rotateX(90deg); - opacity: 0; - } -} - -.flipOutX { - -webkit-animation-name: flipOutX; - animation-name: flipOutX; - -webkit-backface-visibility: visible !important; - -ms-backface-visibility: visible !important; - backface-visibility: visible !important; -} - -@-webkit-keyframes flipOutY { - 0% { - -webkit-transform: perspective(400px) rotateY(0deg); - transform: perspective(400px) rotateY(0deg); - opacity: 1; - } - - 100% { - -webkit-transform: perspective(400px) rotateY(90deg); - transform: perspective(400px) rotateY(90deg); - opacity: 0; - } -} - -@keyframes flipOutY { - 0% { - -webkit-transform: perspective(400px) rotateY(0deg); - -ms-transform: perspective(400px) rotateY(0deg); - transform: perspective(400px) rotateY(0deg); - opacity: 1; - } - - 100% { - -webkit-transform: perspective(400px) rotateY(90deg); - -ms-transform: perspective(400px) rotateY(90deg); - transform: perspective(400px) rotateY(90deg); - opacity: 0; - } -} - -.flipOutY { - -webkit-backface-visibility: visible !important; - -ms-backface-visibility: visible !important; - backface-visibility: visible !important; - -webkit-animation-name: flipOutY; - animation-name: flipOutY; -} - -@-webkit-keyframes lightSpeedIn { - 0% { - -webkit-transform: translateX(100%) skewX(-30deg); - transform: translateX(100%) skewX(-30deg); - opacity: 0; - } - - 60% { - -webkit-transform: translateX(-20%) skewX(30deg); - transform: translateX(-20%) skewX(30deg); - opacity: 1; - } - - 80% { - -webkit-transform: translateX(0%) skewX(-15deg); - transform: translateX(0%) skewX(-15deg); - opacity: 1; - } - - 100% { - -webkit-transform: translateX(0%) skewX(0deg); - transform: translateX(0%) skewX(0deg); - opacity: 1; - } -} - -@keyframes lightSpeedIn { - 0% { - -webkit-transform: translateX(100%) skewX(-30deg); - -ms-transform: translateX(100%) skewX(-30deg); - transform: translateX(100%) skewX(-30deg); - opacity: 0; - } - - 60% { - -webkit-transform: translateX(-20%) skewX(30deg); - -ms-transform: translateX(-20%) skewX(30deg); - transform: translateX(-20%) skewX(30deg); - opacity: 1; - } - - 80% { - -webkit-transform: translateX(0%) skewX(-15deg); - -ms-transform: translateX(0%) skewX(-15deg); - transform: translateX(0%) skewX(-15deg); - opacity: 1; - } - - 100% { - -webkit-transform: translateX(0%) skewX(0deg); - -ms-transform: translateX(0%) skewX(0deg); - transform: translateX(0%) skewX(0deg); - opacity: 1; - } -} - -.lightSpeedIn { - -webkit-animation-name: lightSpeedIn; - animation-name: lightSpeedIn; - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; -} - -@-webkit-keyframes lightSpeedOut { - 0% { - -webkit-transform: translateX(0%) skewX(0deg); - transform: translateX(0%) skewX(0deg); - opacity: 1; - } - - 100% { - -webkit-transform: translateX(100%) skewX(-30deg); - transform: translateX(100%) skewX(-30deg); - opacity: 0; - } -} - -@keyframes lightSpeedOut { - 0% { - -webkit-transform: translateX(0%) skewX(0deg); - -ms-transform: translateX(0%) skewX(0deg); - transform: translateX(0%) skewX(0deg); - opacity: 1; - } - - 100% { - -webkit-transform: translateX(100%) skewX(-30deg); - -ms-transform: translateX(100%) skewX(-30deg); - transform: translateX(100%) skewX(-30deg); - opacity: 0; - } -} - -.lightSpeedOut { - -webkit-animation-name: lightSpeedOut; - animation-name: lightSpeedOut; - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; -} - -@-webkit-keyframes rotateIn { - 0% { - -webkit-transform-origin: center center; - transform-origin: center center; - -webkit-transform: rotate(-200deg); - transform: rotate(-200deg); - opacity: 0; - } - - 100% { - -webkit-transform-origin: center center; - transform-origin: center center; - -webkit-transform: rotate(0); - transform: rotate(0); - opacity: 1; - } -} - -@keyframes rotateIn { - 0% { - -webkit-transform-origin: center center; - -ms-transform-origin: center center; - transform-origin: center center; - -webkit-transform: rotate(-200deg); - -ms-transform: rotate(-200deg); - transform: rotate(-200deg); - opacity: 0; - } - - 100% { - -webkit-transform-origin: center center; - -ms-transform-origin: center center; - transform-origin: center center; - -webkit-transform: rotate(0); - -ms-transform: rotate(0); - transform: rotate(0); - opacity: 1; - } -} - -.rotateIn { - -webkit-animation-name: rotateIn; - animation-name: rotateIn; -} - -@-webkit-keyframes rotateInDownLeft { - 0% { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate(-90deg); - transform: rotate(-90deg); - opacity: 0; - } - - 100% { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate(0); - transform: rotate(0); - opacity: 1; - } -} - -@keyframes rotateInDownLeft { - 0% { - -webkit-transform-origin: left bottom; - -ms-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate(-90deg); - -ms-transform: rotate(-90deg); - transform: rotate(-90deg); - opacity: 0; - } - - 100% { - -webkit-transform-origin: left bottom; - -ms-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate(0); - -ms-transform: rotate(0); - transform: rotate(0); - opacity: 1; - } -} - -.rotateInDownLeft { - -webkit-animation-name: rotateInDownLeft; - animation-name: rotateInDownLeft; -} - -@-webkit-keyframes rotateInDownRight { - 0% { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate(90deg); - transform: rotate(90deg); - opacity: 0; - } - - 100% { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate(0); - transform: rotate(0); - opacity: 1; - } -} - -@keyframes rotateInDownRight { - 0% { - -webkit-transform-origin: right bottom; - -ms-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate(90deg); - -ms-transform: rotate(90deg); - transform: rotate(90deg); - opacity: 0; - } - - 100% { - -webkit-transform-origin: right bottom; - -ms-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate(0); - -ms-transform: rotate(0); - transform: rotate(0); - opacity: 1; - } -} - -.rotateInDownRight { - -webkit-animation-name: rotateInDownRight; - animation-name: rotateInDownRight; -} - -@-webkit-keyframes rotateInUpLeft { - 0% { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate(90deg); - transform: rotate(90deg); - opacity: 0; - } - - 100% { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate(0); - transform: rotate(0); - opacity: 1; - } -} - -@keyframes rotateInUpLeft { - 0% { - -webkit-transform-origin: left bottom; - -ms-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate(90deg); - -ms-transform: rotate(90deg); - transform: rotate(90deg); - opacity: 0; - } - - 100% { - -webkit-transform-origin: left bottom; - -ms-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate(0); - -ms-transform: rotate(0); - transform: rotate(0); - opacity: 1; - } -} - -.rotateInUpLeft { - -webkit-animation-name: rotateInUpLeft; - animation-name: rotateInUpLeft; -} - -@-webkit-keyframes rotateInUpRight { - 0% { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate(-90deg); - transform: rotate(-90deg); - opacity: 0; - } - - 100% { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate(0); - transform: rotate(0); - opacity: 1; - } -} - -@keyframes rotateInUpRight { - 0% { - -webkit-transform-origin: right bottom; - -ms-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate(-90deg); - -ms-transform: rotate(-90deg); - transform: rotate(-90deg); - opacity: 0; - } - - 100% { - -webkit-transform-origin: right bottom; - -ms-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate(0); - -ms-transform: rotate(0); - transform: rotate(0); - opacity: 1; - } -} - -.rotateInUpRight { - -webkit-animation-name: rotateInUpRight; - animation-name: rotateInUpRight; -} - -@-webkit-keyframes rotateOut { - 0% { - -webkit-transform-origin: center center; - transform-origin: center center; - -webkit-transform: rotate(0); - transform: rotate(0); - opacity: 1; - } - - 100% { - -webkit-transform-origin: center center; - transform-origin: center center; - -webkit-transform: rotate(200deg); - transform: rotate(200deg); - opacity: 0; - } -} - -@keyframes rotateOut { - 0% { - -webkit-transform-origin: center center; - -ms-transform-origin: center center; - transform-origin: center center; - -webkit-transform: rotate(0); - -ms-transform: rotate(0); - transform: rotate(0); - opacity: 1; - } - - 100% { - -webkit-transform-origin: center center; - -ms-transform-origin: center center; - transform-origin: center center; - -webkit-transform: rotate(200deg); - -ms-transform: rotate(200deg); - transform: rotate(200deg); - opacity: 0; - } -} - -.rotateOut { - -webkit-animation-name: rotateOut; - animation-name: rotateOut; -} - -@-webkit-keyframes rotateOutDownLeft { - 0% { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate(0); - transform: rotate(0); - opacity: 1; - } - - 100% { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate(90deg); - transform: rotate(90deg); - opacity: 0; - } -} - -@keyframes rotateOutDownLeft { - 0% { - -webkit-transform-origin: left bottom; - -ms-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate(0); - -ms-transform: rotate(0); - transform: rotate(0); - opacity: 1; - } - - 100% { - -webkit-transform-origin: left bottom; - -ms-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate(90deg); - -ms-transform: rotate(90deg); - transform: rotate(90deg); - opacity: 0; - } -} - -.rotateOutDownLeft { - -webkit-animation-name: rotateOutDownLeft; - animation-name: rotateOutDownLeft; -} - -@-webkit-keyframes rotateOutDownRight { - 0% { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate(0); - transform: rotate(0); - opacity: 1; - } - - 100% { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate(-90deg); - transform: rotate(-90deg); - opacity: 0; - } -} - -@keyframes rotateOutDownRight { - 0% { - -webkit-transform-origin: right bottom; - -ms-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate(0); - -ms-transform: rotate(0); - transform: rotate(0); - opacity: 1; - } - - 100% { - -webkit-transform-origin: right bottom; - -ms-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate(-90deg); - -ms-transform: rotate(-90deg); - transform: rotate(-90deg); - opacity: 0; - } -} - -.rotateOutDownRight { - -webkit-animation-name: rotateOutDownRight; - animation-name: rotateOutDownRight; -} - -@-webkit-keyframes rotateOutUpLeft { - 0% { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate(0); - transform: rotate(0); - opacity: 1; - } - - 100% { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate(-90deg); - transform: rotate(-90deg); - opacity: 0; - } -} - -@keyframes rotateOutUpLeft { - 0% { - -webkit-transform-origin: left bottom; - -ms-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate(0); - -ms-transform: rotate(0); - transform: rotate(0); - opacity: 1; - } - - 100% { - -webkit-transform-origin: left bottom; - -ms-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate(-90deg); - -ms-transform: rotate(-90deg); - transform: rotate(-90deg); - opacity: 0; - } -} - -.rotateOutUpLeft { - -webkit-animation-name: rotateOutUpLeft; - animation-name: rotateOutUpLeft; -} - -@-webkit-keyframes rotateOutUpRight { - 0% { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate(0); - transform: rotate(0); - opacity: 1; - } - - 100% { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate(90deg); - transform: rotate(90deg); - opacity: 0; - } -} - -@keyframes rotateOutUpRight { - 0% { - -webkit-transform-origin: right bottom; - -ms-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate(0); - -ms-transform: rotate(0); - transform: rotate(0); - opacity: 1; - } - - 100% { - -webkit-transform-origin: right bottom; - -ms-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate(90deg); - -ms-transform: rotate(90deg); - transform: rotate(90deg); - opacity: 0; - } -} - -.rotateOutUpRight { - -webkit-animation-name: rotateOutUpRight; - animation-name: rotateOutUpRight; -} - -@-webkit-keyframes slideInDown { - 0% { - opacity: 0; - -webkit-transform: translateY(-2000px); - transform: translateY(-2000px); - } - - 100% { - -webkit-transform: translateY(0); - transform: translateY(0); - } -} - -@keyframes slideInDown { - 0% { - opacity: 0; - -webkit-transform: translateY(-2000px); - -ms-transform: translateY(-2000px); - transform: translateY(-2000px); - } - - 100% { - -webkit-transform: translateY(0); - -ms-transform: translateY(0); - transform: translateY(0); - } -} - -.slideInDown { - -webkit-animation-name: slideInDown; - animation-name: slideInDown; -} - -@-webkit-keyframes slideInLeft { - 0% { - opacity: 0; - -webkit-transform: translateX(-2000px); - transform: translateX(-2000px); - } - - 100% { - -webkit-transform: translateX(0); - transform: translateX(0); - } -} - -@keyframes slideInLeft { - 0% { - opacity: 0; - -webkit-transform: translateX(-2000px); - -ms-transform: translateX(-2000px); - transform: translateX(-2000px); - } - - 100% { - -webkit-transform: translateX(0); - -ms-transform: translateX(0); - transform: translateX(0); - } -} - -.slideInLeft { - -webkit-animation-name: slideInLeft; - animation-name: slideInLeft; -} - -@-webkit-keyframes slideInRight { - 0% { - opacity: 0; - -webkit-transform: translateX(2000px); - transform: translateX(2000px); - } - - 100% { - -webkit-transform: translateX(0); - transform: translateX(0); - } -} - -@keyframes slideInRight { - 0% { - opacity: 0; - -webkit-transform: translateX(2000px); - -ms-transform: translateX(2000px); - transform: translateX(2000px); - } - - 100% { - -webkit-transform: translateX(0); - -ms-transform: translateX(0); - transform: translateX(0); - } -} - -.slideInRight { - -webkit-animation-name: slideInRight; - animation-name: slideInRight; -} - -@-webkit-keyframes slideOutLeft { - 0% { - -webkit-transform: translateX(0); - transform: translateX(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateX(-2000px); - transform: translateX(-2000px); - } -} - -@keyframes slideOutLeft { - 0% { - -webkit-transform: translateX(0); - -ms-transform: translateX(0); - transform: translateX(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateX(-2000px); - -ms-transform: translateX(-2000px); - transform: translateX(-2000px); - } -} - -.slideOutLeft { - -webkit-animation-name: slideOutLeft; - animation-name: slideOutLeft; -} - -@-webkit-keyframes slideOutRight { - 0% { - -webkit-transform: translateX(0); - transform: translateX(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateX(2000px); - transform: translateX(2000px); - } -} - -@keyframes slideOutRight { - 0% { - -webkit-transform: translateX(0); - -ms-transform: translateX(0); - transform: translateX(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateX(2000px); - -ms-transform: translateX(2000px); - transform: translateX(2000px); - } -} - -.slideOutRight { - -webkit-animation-name: slideOutRight; - animation-name: slideOutRight; -} - -@-webkit-keyframes slideOutUp { - 0% { - -webkit-transform: translateY(0); - transform: translateY(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateY(-2000px); - transform: translateY(-2000px); - } -} - -@keyframes slideOutUp { - 0% { - -webkit-transform: translateY(0); - -ms-transform: translateY(0); - transform: translateY(0); - } - - 100% { - opacity: 0; - -webkit-transform: translateY(-2000px); - -ms-transform: translateY(-2000px); - transform: translateY(-2000px); - } -} - -.slideOutUp { - -webkit-animation-name: slideOutUp; - animation-name: slideOutUp; -} - -@-webkit-keyframes hinge { - 0% { - -webkit-transform: rotate(0); - transform: rotate(0); - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - } - - 20%, 60% { - -webkit-transform: rotate(80deg); - transform: rotate(80deg); - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - } - - 40% { - -webkit-transform: rotate(60deg); - transform: rotate(60deg); - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - } - - 80% { - -webkit-transform: rotate(60deg) translateY(0); - transform: rotate(60deg) translateY(0); - opacity: 1; - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - } - - 100% { - -webkit-transform: translateY(700px); - transform: translateY(700px); - opacity: 0; - } -} - -@keyframes hinge { - 0% { - -webkit-transform: rotate(0); - -ms-transform: rotate(0); - transform: rotate(0); - -webkit-transform-origin: top left; - -ms-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - } - - 20%, 60% { - -webkit-transform: rotate(80deg); - -ms-transform: rotate(80deg); - transform: rotate(80deg); - -webkit-transform-origin: top left; - -ms-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - } - - 40% { - -webkit-transform: rotate(60deg); - -ms-transform: rotate(60deg); - transform: rotate(60deg); - -webkit-transform-origin: top left; - -ms-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - } - - 80% { - -webkit-transform: rotate(60deg) translateY(0); - -ms-transform: rotate(60deg) translateY(0); - transform: rotate(60deg) translateY(0); - opacity: 1; - -webkit-transform-origin: top left; - -ms-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - } - - 100% { - -webkit-transform: translateY(700px); - -ms-transform: translateY(700px); - transform: translateY(700px); - opacity: 0; - } -} - -.hinge { - -webkit-animation-name: hinge; - animation-name: hinge; -} - -/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ - -@-webkit-keyframes rollIn { - 0% { - opacity: 0; - -webkit-transform: translateX(-100%) rotate(-120deg); - transform: translateX(-100%) rotate(-120deg); - } - - 100% { - opacity: 1; - -webkit-transform: translateX(0px) rotate(0deg); - transform: translateX(0px) rotate(0deg); - } -} - -@keyframes rollIn { - 0% { - opacity: 0; - -webkit-transform: translateX(-100%) rotate(-120deg); - -ms-transform: translateX(-100%) rotate(-120deg); - transform: translateX(-100%) rotate(-120deg); - } - - 100% { - opacity: 1; - -webkit-transform: translateX(0px) rotate(0deg); - -ms-transform: translateX(0px) rotate(0deg); - transform: translateX(0px) rotate(0deg); - } -} - -.rollIn { - -webkit-animation-name: rollIn; - animation-name: rollIn; -} - -/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ - -@-webkit-keyframes rollOut { - 0% { - opacity: 1; - -webkit-transform: translateX(0px) rotate(0deg); - transform: translateX(0px) rotate(0deg); - } - - 100% { - opacity: 0; - -webkit-transform: translateX(100%) rotate(120deg); - transform: translateX(100%) rotate(120deg); - } -} - -@keyframes rollOut { - 0% { - opacity: 1; - -webkit-transform: translateX(0px) rotate(0deg); - -ms-transform: translateX(0px) rotate(0deg); - transform: translateX(0px) rotate(0deg); - } - - 100% { - opacity: 0; - -webkit-transform: translateX(100%) rotate(120deg); - -ms-transform: translateX(100%) rotate(120deg); - transform: translateX(100%) rotate(120deg); - } -} - -.rollOut { - -webkit-animation-name: rollOut; - animation-name: rollOut; +@charset "UTF-8"; + + +/*! +Animate.css - http://daneden.me/animate +Licensed under the MIT license + +Copyright (c) 2013 Daniel Eden + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +.animated { + -webkit-animation-duration: 1s; + animation-duration: 1s; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; +} + +.animated.hinge { + -webkit-animation-duration: 2s; + animation-duration: 2s; +} + +@-webkit-keyframes bounce { + 0%, 20%, 50%, 80%, 100% { + -webkit-transform: translateY(0); + transform: translateY(0); + } + + 40% { + -webkit-transform: translateY(-30px); + transform: translateY(-30px); + } + + 60% { + -webkit-transform: translateY(-15px); + transform: translateY(-15px); + } +} + +@keyframes bounce { + 0%, 20%, 50%, 80%, 100% { + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } + + 40% { + -webkit-transform: translateY(-30px); + -ms-transform: translateY(-30px); + transform: translateY(-30px); + } + + 60% { + -webkit-transform: translateY(-15px); + -ms-transform: translateY(-15px); + transform: translateY(-15px); + } +} + +.bounce { + -webkit-animation-name: bounce; + animation-name: bounce; +} + +@-webkit-keyframes flash { + 0%, 50%, 100% { + opacity: 1; + } + + 25%, 75% { + opacity: 0; + } +} + +@keyframes flash { + 0%, 50%, 100% { + opacity: 1; + } + + 25%, 75% { + opacity: 0; + } +} + +.flash { + -webkit-animation-name: flash; + animation-name: flash; +} + +/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ + +@-webkit-keyframes pulse { + 0% { + -webkit-transform: scale(1); + transform: scale(1); + } + + 50% { + -webkit-transform: scale(1.1); + transform: scale(1.1); + } + + 100% { + -webkit-transform: scale(1); + transform: scale(1); + } +} + +@keyframes pulse { + 0% { + -webkit-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } + + 50% { + -webkit-transform: scale(1.1); + -ms-transform: scale(1.1); + transform: scale(1.1); + } + + 100% { + -webkit-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } +} + +.pulse { + -webkit-animation-name: pulse; + animation-name: pulse; +} + +@-webkit-keyframes shake { + 0%, 100% { + -webkit-transform: translateX(0); + transform: translateX(0); + } + + 10%, 30%, 50%, 70%, 90% { + -webkit-transform: translateX(-10px); + transform: translateX(-10px); + } + + 20%, 40%, 60%, 80% { + -webkit-transform: translateX(10px); + transform: translateX(10px); + } +} + +@keyframes shake { + 0%, 100% { + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } + + 10%, 30%, 50%, 70%, 90% { + -webkit-transform: translateX(-10px); + -ms-transform: translateX(-10px); + transform: translateX(-10px); + } + + 20%, 40%, 60%, 80% { + -webkit-transform: translateX(10px); + -ms-transform: translateX(10px); + transform: translateX(10px); + } +} + +.shake { + -webkit-animation-name: shake; + animation-name: shake; +} + +@-webkit-keyframes swing { + 20% { + -webkit-transform: rotate(15deg); + transform: rotate(15deg); + } + + 40% { + -webkit-transform: rotate(-10deg); + transform: rotate(-10deg); + } + + 60% { + -webkit-transform: rotate(5deg); + transform: rotate(5deg); + } + + 80% { + -webkit-transform: rotate(-5deg); + transform: rotate(-5deg); + } + + 100% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } +} + +@keyframes swing { + 20% { + -webkit-transform: rotate(15deg); + -ms-transform: rotate(15deg); + transform: rotate(15deg); + } + + 40% { + -webkit-transform: rotate(-10deg); + -ms-transform: rotate(-10deg); + transform: rotate(-10deg); + } + + 60% { + -webkit-transform: rotate(5deg); + -ms-transform: rotate(5deg); + transform: rotate(5deg); + } + + 80% { + -webkit-transform: rotate(-5deg); + -ms-transform: rotate(-5deg); + transform: rotate(-5deg); + } + + 100% { + -webkit-transform: rotate(0deg); + -ms-transform: rotate(0deg); + transform: rotate(0deg); + } +} + +.swing { + -webkit-transform-origin: top center; + -ms-transform-origin: top center; + transform-origin: top center; + -webkit-animation-name: swing; + animation-name: swing; +} + +@-webkit-keyframes tada { + 0% { + -webkit-transform: scale(1); + transform: scale(1); + } + + 10%, 20% { + -webkit-transform: scale(0.9) rotate(-3deg); + transform: scale(0.9) rotate(-3deg); + } + + 30%, 50%, 70%, 90% { + -webkit-transform: scale(1.1) rotate(3deg); + transform: scale(1.1) rotate(3deg); + } + + 40%, 60%, 80% { + -webkit-transform: scale(1.1) rotate(-3deg); + transform: scale(1.1) rotate(-3deg); + } + + 100% { + -webkit-transform: scale(1) rotate(0); + transform: scale(1) rotate(0); + } +} + +@keyframes tada { + 0% { + -webkit-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } + + 10%, 20% { + -webkit-transform: scale(0.9) rotate(-3deg); + -ms-transform: scale(0.9) rotate(-3deg); + transform: scale(0.9) rotate(-3deg); + } + + 30%, 50%, 70%, 90% { + -webkit-transform: scale(1.1) rotate(3deg); + -ms-transform: scale(1.1) rotate(3deg); + transform: scale(1.1) rotate(3deg); + } + + 40%, 60%, 80% { + -webkit-transform: scale(1.1) rotate(-3deg); + -ms-transform: scale(1.1) rotate(-3deg); + transform: scale(1.1) rotate(-3deg); + } + + 100% { + -webkit-transform: scale(1) rotate(0); + -ms-transform: scale(1) rotate(0); + transform: scale(1) rotate(0); + } +} + +.tada { + -webkit-animation-name: tada; + animation-name: tada; +} + +/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ + +@-webkit-keyframes wobble { + 0% { + -webkit-transform: translateX(0%); + transform: translateX(0%); + } + + 15% { + -webkit-transform: translateX(-25%) rotate(-5deg); + transform: translateX(-25%) rotate(-5deg); + } + + 30% { + -webkit-transform: translateX(20%) rotate(3deg); + transform: translateX(20%) rotate(3deg); + } + + 45% { + -webkit-transform: translateX(-15%) rotate(-3deg); + transform: translateX(-15%) rotate(-3deg); + } + + 60% { + -webkit-transform: translateX(10%) rotate(2deg); + transform: translateX(10%) rotate(2deg); + } + + 75% { + -webkit-transform: translateX(-5%) rotate(-1deg); + transform: translateX(-5%) rotate(-1deg); + } + + 100% { + -webkit-transform: translateX(0%); + transform: translateX(0%); + } +} + +@keyframes wobble { + 0% { + -webkit-transform: translateX(0%); + -ms-transform: translateX(0%); + transform: translateX(0%); + } + + 15% { + -webkit-transform: translateX(-25%) rotate(-5deg); + -ms-transform: translateX(-25%) rotate(-5deg); + transform: translateX(-25%) rotate(-5deg); + } + + 30% { + -webkit-transform: translateX(20%) rotate(3deg); + -ms-transform: translateX(20%) rotate(3deg); + transform: translateX(20%) rotate(3deg); + } + + 45% { + -webkit-transform: translateX(-15%) rotate(-3deg); + -ms-transform: translateX(-15%) rotate(-3deg); + transform: translateX(-15%) rotate(-3deg); + } + + 60% { + -webkit-transform: translateX(10%) rotate(2deg); + -ms-transform: translateX(10%) rotate(2deg); + transform: translateX(10%) rotate(2deg); + } + + 75% { + -webkit-transform: translateX(-5%) rotate(-1deg); + -ms-transform: translateX(-5%) rotate(-1deg); + transform: translateX(-5%) rotate(-1deg); + } + + 100% { + -webkit-transform: translateX(0%); + -ms-transform: translateX(0%); + transform: translateX(0%); + } +} + +.wobble { + -webkit-animation-name: wobble; + animation-name: wobble; +} + +@-webkit-keyframes bounceIn { + 0% { + opacity: 0; + -webkit-transform: scale(.3); + transform: scale(.3); + } + + 50% { + opacity: 1; + -webkit-transform: scale(1.05); + transform: scale(1.05); + } + + 70% { + -webkit-transform: scale(.9); + transform: scale(.9); + } + + 100% { + -webkit-transform: scale(1); + transform: scale(1); + } +} + +@keyframes bounceIn { + 0% { + opacity: 0; + -webkit-transform: scale(.3); + -ms-transform: scale(.3); + transform: scale(.3); + } + + 50% { + opacity: 1; + -webkit-transform: scale(1.05); + -ms-transform: scale(1.05); + transform: scale(1.05); + } + + 70% { + -webkit-transform: scale(.9); + -ms-transform: scale(.9); + transform: scale(.9); + } + + 100% { + -webkit-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } +} + +.bounceIn { + -webkit-animation-name: bounceIn; + animation-name: bounceIn; +} + +@-webkit-keyframes bounceInDown { + 0% { + opacity: 0; + -webkit-transform: translateY(-2000px); + transform: translateY(-2000px); + } + + 60% { + opacity: 1; + -webkit-transform: translateY(30px); + transform: translateY(30px); + } + + 80% { + -webkit-transform: translateY(-10px); + transform: translateY(-10px); + } + + 100% { + -webkit-transform: translateY(0); + transform: translateY(0); + } +} + +@keyframes bounceInDown { + 0% { + opacity: 0; + -webkit-transform: translateY(-2000px); + -ms-transform: translateY(-2000px); + transform: translateY(-2000px); + } + + 60% { + opacity: 1; + -webkit-transform: translateY(30px); + -ms-transform: translateY(30px); + transform: translateY(30px); + } + + 80% { + -webkit-transform: translateY(-10px); + -ms-transform: translateY(-10px); + transform: translateY(-10px); + } + + 100% { + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} + +.bounceInDown { + -webkit-animation-name: bounceInDown; + animation-name: bounceInDown; +} + +@-webkit-keyframes bounceInLeft { + 0% { + opacity: 0; + -webkit-transform: translateX(-2000px); + transform: translateX(-2000px); + } + + 60% { + opacity: 1; + -webkit-transform: translateX(30px); + transform: translateX(30px); + } + + 80% { + -webkit-transform: translateX(-10px); + transform: translateX(-10px); + } + + 100% { + -webkit-transform: translateX(0); + transform: translateX(0); + } +} + +@keyframes bounceInLeft { + 0% { + opacity: 0; + -webkit-transform: translateX(-2000px); + -ms-transform: translateX(-2000px); + transform: translateX(-2000px); + } + + 60% { + opacity: 1; + -webkit-transform: translateX(30px); + -ms-transform: translateX(30px); + transform: translateX(30px); + } + + 80% { + -webkit-transform: translateX(-10px); + -ms-transform: translateX(-10px); + transform: translateX(-10px); + } + + 100% { + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } +} + +.bounceInLeft { + -webkit-animation-name: bounceInLeft; + animation-name: bounceInLeft; +} + +@-webkit-keyframes bounceInRight { + 0% { + opacity: 0; + -webkit-transform: translateX(2000px); + transform: translateX(2000px); + } + + 60% { + opacity: 1; + -webkit-transform: translateX(-30px); + transform: translateX(-30px); + } + + 80% { + -webkit-transform: translateX(10px); + transform: translateX(10px); + } + + 100% { + -webkit-transform: translateX(0); + transform: translateX(0); + } +} + +@keyframes bounceInRight { + 0% { + opacity: 0; + -webkit-transform: translateX(2000px); + -ms-transform: translateX(2000px); + transform: translateX(2000px); + } + + 60% { + opacity: 1; + -webkit-transform: translateX(-30px); + -ms-transform: translateX(-30px); + transform: translateX(-30px); + } + + 80% { + -webkit-transform: translateX(10px); + -ms-transform: translateX(10px); + transform: translateX(10px); + } + + 100% { + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } +} + +.bounceInRight { + -webkit-animation-name: bounceInRight; + animation-name: bounceInRight; +} + +@-webkit-keyframes bounceInUp { + 0% { + opacity: 0; + -webkit-transform: translateY(2000px); + transform: translateY(2000px); + } + + 60% { + opacity: 1; + -webkit-transform: translateY(-30px); + transform: translateY(-30px); + } + + 80% { + -webkit-transform: translateY(10px); + transform: translateY(10px); + } + + 100% { + -webkit-transform: translateY(0); + transform: translateY(0); + } +} + +@keyframes bounceInUp { + 0% { + opacity: 0; + -webkit-transform: translateY(2000px); + -ms-transform: translateY(2000px); + transform: translateY(2000px); + } + + 60% { + opacity: 1; + -webkit-transform: translateY(-30px); + -ms-transform: translateY(-30px); + transform: translateY(-30px); + } + + 80% { + -webkit-transform: translateY(10px); + -ms-transform: translateY(10px); + transform: translateY(10px); + } + + 100% { + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} + +.bounceInUp { + -webkit-animation-name: bounceInUp; + animation-name: bounceInUp; +} + +@-webkit-keyframes bounceOut { + 0% { + -webkit-transform: scale(1); + transform: scale(1); + } + + 25% { + -webkit-transform: scale(.95); + transform: scale(.95); + } + + 50% { + opacity: 1; + -webkit-transform: scale(1.1); + transform: scale(1.1); + } + + 100% { + opacity: 0; + -webkit-transform: scale(.3); + transform: scale(.3); + } +} + +@keyframes bounceOut { + 0% { + -webkit-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } + + 25% { + -webkit-transform: scale(.95); + -ms-transform: scale(.95); + transform: scale(.95); + } + + 50% { + opacity: 1; + -webkit-transform: scale(1.1); + -ms-transform: scale(1.1); + transform: scale(1.1); + } + + 100% { + opacity: 0; + -webkit-transform: scale(.3); + -ms-transform: scale(.3); + transform: scale(.3); + } +} + +.bounceOut { + -webkit-animation-name: bounceOut; + animation-name: bounceOut; +} + +@-webkit-keyframes bounceOutDown { + 0% { + -webkit-transform: translateY(0); + transform: translateY(0); + } + + 20% { + opacity: 1; + -webkit-transform: translateY(-20px); + transform: translateY(-20px); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(2000px); + transform: translateY(2000px); + } +} + +@keyframes bounceOutDown { + 0% { + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } + + 20% { + opacity: 1; + -webkit-transform: translateY(-20px); + -ms-transform: translateY(-20px); + transform: translateY(-20px); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(2000px); + -ms-transform: translateY(2000px); + transform: translateY(2000px); + } +} + +.bounceOutDown { + -webkit-animation-name: bounceOutDown; + animation-name: bounceOutDown; +} + +@-webkit-keyframes bounceOutLeft { + 0% { + -webkit-transform: translateX(0); + transform: translateX(0); + } + + 20% { + opacity: 1; + -webkit-transform: translateX(20px); + transform: translateX(20px); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(-2000px); + transform: translateX(-2000px); + } +} + +@keyframes bounceOutLeft { + 0% { + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } + + 20% { + opacity: 1; + -webkit-transform: translateX(20px); + -ms-transform: translateX(20px); + transform: translateX(20px); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(-2000px); + -ms-transform: translateX(-2000px); + transform: translateX(-2000px); + } +} + +.bounceOutLeft { + -webkit-animation-name: bounceOutLeft; + animation-name: bounceOutLeft; +} + +@-webkit-keyframes bounceOutRight { + 0% { + -webkit-transform: translateX(0); + transform: translateX(0); + } + + 20% { + opacity: 1; + -webkit-transform: translateX(-20px); + transform: translateX(-20px); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(2000px); + transform: translateX(2000px); + } +} + +@keyframes bounceOutRight { + 0% { + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } + + 20% { + opacity: 1; + -webkit-transform: translateX(-20px); + -ms-transform: translateX(-20px); + transform: translateX(-20px); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(2000px); + -ms-transform: translateX(2000px); + transform: translateX(2000px); + } +} + +.bounceOutRight { + -webkit-animation-name: bounceOutRight; + animation-name: bounceOutRight; +} + +@-webkit-keyframes bounceOutUp { + 0% { + -webkit-transform: translateY(0); + transform: translateY(0); + } + + 20% { + opacity: 1; + -webkit-transform: translateY(20px); + transform: translateY(20px); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(-2000px); + transform: translateY(-2000px); + } +} + +@keyframes bounceOutUp { + 0% { + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } + + 20% { + opacity: 1; + -webkit-transform: translateY(20px); + -ms-transform: translateY(20px); + transform: translateY(20px); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(-2000px); + -ms-transform: translateY(-2000px); + transform: translateY(-2000px); + } +} + +.bounceOutUp { + -webkit-animation-name: bounceOutUp; + animation-name: bounceOutUp; +} + +@-webkit-keyframes fadeIn { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@keyframes fadeIn { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +.fadeIn { + -webkit-animation-name: fadeIn; + animation-name: fadeIn; +} + +@-webkit-keyframes fadeInDown { + 0% { + opacity: 0; + -webkit-transform: translateY(-20px); + transform: translateY(-20px); + } + + 100% { + opacity: 1; + -webkit-transform: translateY(0); + transform: translateY(0); + } +} + +@keyframes fadeInDown { + 0% { + opacity: 0; + -webkit-transform: translateY(-20px); + -ms-transform: translateY(-20px); + transform: translateY(-20px); + } + + 100% { + opacity: 1; + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} + +.fadeInDown { + -webkit-animation-name: fadeInDown; + animation-name: fadeInDown; +} + +@-webkit-keyframes fadeInDownBig { + 0% { + opacity: 0; + -webkit-transform: translateY(-2000px); + transform: translateY(-2000px); + } + + 100% { + opacity: 1; + -webkit-transform: translateY(0); + transform: translateY(0); + } +} + +@keyframes fadeInDownBig { + 0% { + opacity: 0; + -webkit-transform: translateY(-2000px); + -ms-transform: translateY(-2000px); + transform: translateY(-2000px); + } + + 100% { + opacity: 1; + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} + +.fadeInDownBig { + -webkit-animation-name: fadeInDownBig; + animation-name: fadeInDownBig; +} + +@-webkit-keyframes fadeInLeft { + 0% { + opacity: 0; + -webkit-transform: translateX(-20px); + transform: translateX(-20px); + } + + 100% { + opacity: 1; + -webkit-transform: translateX(0); + transform: translateX(0); + } +} + +@keyframes fadeInLeft { + 0% { + opacity: 0; + -webkit-transform: translateX(-20px); + -ms-transform: translateX(-20px); + transform: translateX(-20px); + } + + 100% { + opacity: 1; + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } +} + +.fadeInLeft { + -webkit-animation-name: fadeInLeft; + animation-name: fadeInLeft; +} + +@-webkit-keyframes fadeInLeftBig { + 0% { + opacity: 0; + -webkit-transform: translateX(-2000px); + transform: translateX(-2000px); + } + + 100% { + opacity: 1; + -webkit-transform: translateX(0); + transform: translateX(0); + } +} + +@keyframes fadeInLeftBig { + 0% { + opacity: 0; + -webkit-transform: translateX(-2000px); + -ms-transform: translateX(-2000px); + transform: translateX(-2000px); + } + + 100% { + opacity: 1; + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } +} + +.fadeInLeftBig { + -webkit-animation-name: fadeInLeftBig; + animation-name: fadeInLeftBig; +} + +@-webkit-keyframes fadeInRight { + 0% { + opacity: 0; + -webkit-transform: translateX(20px); + transform: translateX(20px); + } + + 100% { + opacity: 1; + -webkit-transform: translateX(0); + transform: translateX(0); + } +} + +@keyframes fadeInRight { + 0% { + opacity: 0; + -webkit-transform: translateX(20px); + -ms-transform: translateX(20px); + transform: translateX(20px); + } + + 100% { + opacity: 1; + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } +} + +.fadeInRight { + -webkit-animation-name: fadeInRight; + animation-name: fadeInRight; +} + +@-webkit-keyframes fadeInRightBig { + 0% { + opacity: 0; + -webkit-transform: translateX(2000px); + transform: translateX(2000px); + } + + 100% { + opacity: 1; + -webkit-transform: translateX(0); + transform: translateX(0); + } +} + +@keyframes fadeInRightBig { + 0% { + opacity: 0; + -webkit-transform: translateX(2000px); + -ms-transform: translateX(2000px); + transform: translateX(2000px); + } + + 100% { + opacity: 1; + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } +} + +.fadeInRightBig { + -webkit-animation-name: fadeInRightBig; + animation-name: fadeInRightBig; +} + +@-webkit-keyframes fadeInUp { + 0% { + opacity: 0; + -webkit-transform: translateY(20px); + transform: translateY(20px); + } + + 100% { + opacity: 1; + -webkit-transform: translateY(0); + transform: translateY(0); + } +} + +@keyframes fadeInUp { + 0% { + opacity: 0; + -webkit-transform: translateY(20px); + -ms-transform: translateY(20px); + transform: translateY(20px); + } + + 100% { + opacity: 1; + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} + +.fadeInUp { + -webkit-animation-name: fadeInUp; + animation-name: fadeInUp; +} + +@-webkit-keyframes fadeInUpBig { + 0% { + opacity: 0; + -webkit-transform: translateY(2000px); + transform: translateY(2000px); + } + + 100% { + opacity: 1; + -webkit-transform: translateY(0); + transform: translateY(0); + } +} + +@keyframes fadeInUpBig { + 0% { + opacity: 0; + -webkit-transform: translateY(2000px); + -ms-transform: translateY(2000px); + transform: translateY(2000px); + } + + 100% { + opacity: 1; + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} + +.fadeInUpBig { + -webkit-animation-name: fadeInUpBig; + animation-name: fadeInUpBig; +} + +@-webkit-keyframes fadeOut { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} + +@keyframes fadeOut { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} + +.fadeOut { + -webkit-animation-name: fadeOut; + animation-name: fadeOut; +} + +@-webkit-keyframes fadeOutDown { + 0% { + opacity: 1; + -webkit-transform: translateY(0); + transform: translateY(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(20px); + transform: translateY(20px); + } +} + +@keyframes fadeOutDown { + 0% { + opacity: 1; + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(20px); + -ms-transform: translateY(20px); + transform: translateY(20px); + } +} + +.fadeOutDown { + -webkit-animation-name: fadeOutDown; + animation-name: fadeOutDown; +} + +@-webkit-keyframes fadeOutDownBig { + 0% { + opacity: 1; + -webkit-transform: translateY(0); + transform: translateY(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(2000px); + transform: translateY(2000px); + } +} + +@keyframes fadeOutDownBig { + 0% { + opacity: 1; + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(2000px); + -ms-transform: translateY(2000px); + transform: translateY(2000px); + } +} + +.fadeOutDownBig { + -webkit-animation-name: fadeOutDownBig; + animation-name: fadeOutDownBig; +} + +@-webkit-keyframes fadeOutLeft { + 0% { + opacity: 1; + -webkit-transform: translateX(0); + transform: translateX(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(-20px); + transform: translateX(-20px); + } +} + +@keyframes fadeOutLeft { + 0% { + opacity: 1; + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(-20px); + -ms-transform: translateX(-20px); + transform: translateX(-20px); + } +} + +.fadeOutLeft { + -webkit-animation-name: fadeOutLeft; + animation-name: fadeOutLeft; +} + +@-webkit-keyframes fadeOutLeftBig { + 0% { + opacity: 1; + -webkit-transform: translateX(0); + transform: translateX(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(-2000px); + transform: translateX(-2000px); + } +} + +@keyframes fadeOutLeftBig { + 0% { + opacity: 1; + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(-2000px); + -ms-transform: translateX(-2000px); + transform: translateX(-2000px); + } +} + +.fadeOutLeftBig { + -webkit-animation-name: fadeOutLeftBig; + animation-name: fadeOutLeftBig; +} + +@-webkit-keyframes fadeOutRight { + 0% { + opacity: 1; + -webkit-transform: translateX(0); + transform: translateX(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(20px); + transform: translateX(20px); + } +} + +@keyframes fadeOutRight { + 0% { + opacity: 1; + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(20px); + -ms-transform: translateX(20px); + transform: translateX(20px); + } +} + +.fadeOutRight { + -webkit-animation-name: fadeOutRight; + animation-name: fadeOutRight; +} + +@-webkit-keyframes fadeOutRightBig { + 0% { + opacity: 1; + -webkit-transform: translateX(0); + transform: translateX(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(2000px); + transform: translateX(2000px); + } +} + +@keyframes fadeOutRightBig { + 0% { + opacity: 1; + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(2000px); + -ms-transform: translateX(2000px); + transform: translateX(2000px); + } +} + +.fadeOutRightBig { + -webkit-animation-name: fadeOutRightBig; + animation-name: fadeOutRightBig; +} + +@-webkit-keyframes fadeOutUp { + 0% { + opacity: 1; + -webkit-transform: translateY(0); + transform: translateY(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(-20px); + transform: translateY(-20px); + } +} + +@keyframes fadeOutUp { + 0% { + opacity: 1; + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(-20px); + -ms-transform: translateY(-20px); + transform: translateY(-20px); + } +} + +.fadeOutUp { + -webkit-animation-name: fadeOutUp; + animation-name: fadeOutUp; +} + +@-webkit-keyframes fadeOutUpBig { + 0% { + opacity: 1; + -webkit-transform: translateY(0); + transform: translateY(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(-2000px); + transform: translateY(-2000px); + } +} + +@keyframes fadeOutUpBig { + 0% { + opacity: 1; + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(-2000px); + -ms-transform: translateY(-2000px); + transform: translateY(-2000px); + } +} + +.fadeOutUpBig { + -webkit-animation-name: fadeOutUpBig; + animation-name: fadeOutUpBig; +} + +@-webkit-keyframes flip { + 0% { + -webkit-transform: perspective(400px) translateZ(0) rotateY(0) scale(1); + transform: perspective(400px) translateZ(0) rotateY(0) scale(1); + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + } + + 40% { + -webkit-transform: perspective(400px) translateZ(150px) rotateY(170deg) scale(1); + transform: perspective(400px) translateZ(150px) rotateY(170deg) scale(1); + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + } + + 50% { + -webkit-transform: perspective(400px) translateZ(150px) rotateY(190deg) scale(1); + transform: perspective(400px) translateZ(150px) rotateY(190deg) scale(1); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + 80% { + -webkit-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(.95); + transform: perspective(400px) translateZ(0) rotateY(360deg) scale(.95); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + 100% { + -webkit-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(1); + transform: perspective(400px) translateZ(0) rotateY(360deg) scale(1); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } +} + +@keyframes flip { + 0% { + -webkit-transform: perspective(400px) translateZ(0) rotateY(0) scale(1); + -ms-transform: perspective(400px) translateZ(0) rotateY(0) scale(1); + transform: perspective(400px) translateZ(0) rotateY(0) scale(1); + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + } + + 40% { + -webkit-transform: perspective(400px) translateZ(150px) rotateY(170deg) scale(1); + -ms-transform: perspective(400px) translateZ(150px) rotateY(170deg) scale(1); + transform: perspective(400px) translateZ(150px) rotateY(170deg) scale(1); + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + } + + 50% { + -webkit-transform: perspective(400px) translateZ(150px) rotateY(190deg) scale(1); + -ms-transform: perspective(400px) translateZ(150px) rotateY(190deg) scale(1); + transform: perspective(400px) translateZ(150px) rotateY(190deg) scale(1); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + 80% { + -webkit-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(.95); + -ms-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(.95); + transform: perspective(400px) translateZ(0) rotateY(360deg) scale(.95); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + 100% { + -webkit-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(1); + -ms-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(1); + transform: perspective(400px) translateZ(0) rotateY(360deg) scale(1); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } +} + +.animated.flip { + -webkit-backface-visibility: visible; + -ms-backface-visibility: visible; + backface-visibility: visible; + -webkit-animation-name: flip; + animation-name: flip; +} + +@-webkit-keyframes flipInX { + 0% { + -webkit-transform: perspective(400px) rotateX(90deg); + transform: perspective(400px) rotateX(90deg); + opacity: 0; + } + + 40% { + -webkit-transform: perspective(400px) rotateX(-10deg); + transform: perspective(400px) rotateX(-10deg); + } + + 70% { + -webkit-transform: perspective(400px) rotateX(10deg); + transform: perspective(400px) rotateX(10deg); + } + + 100% { + -webkit-transform: perspective(400px) rotateX(0deg); + transform: perspective(400px) rotateX(0deg); + opacity: 1; + } +} + +@keyframes flipInX { + 0% { + -webkit-transform: perspective(400px) rotateX(90deg); + -ms-transform: perspective(400px) rotateX(90deg); + transform: perspective(400px) rotateX(90deg); + opacity: 0; + } + + 40% { + -webkit-transform: perspective(400px) rotateX(-10deg); + -ms-transform: perspective(400px) rotateX(-10deg); + transform: perspective(400px) rotateX(-10deg); + } + + 70% { + -webkit-transform: perspective(400px) rotateX(10deg); + -ms-transform: perspective(400px) rotateX(10deg); + transform: perspective(400px) rotateX(10deg); + } + + 100% { + -webkit-transform: perspective(400px) rotateX(0deg); + -ms-transform: perspective(400px) rotateX(0deg); + transform: perspective(400px) rotateX(0deg); + opacity: 1; + } +} + +.flipInX { + -webkit-backface-visibility: visible !important; + -ms-backface-visibility: visible !important; + backface-visibility: visible !important; + -webkit-animation-name: flipInX; + animation-name: flipInX; +} + +@-webkit-keyframes flipInY { + 0% { + -webkit-transform: perspective(400px) rotateY(90deg); + transform: perspective(400px) rotateY(90deg); + opacity: 0; + } + + 40% { + -webkit-transform: perspective(400px) rotateY(-10deg); + transform: perspective(400px) rotateY(-10deg); + } + + 70% { + -webkit-transform: perspective(400px) rotateY(10deg); + transform: perspective(400px) rotateY(10deg); + } + + 100% { + -webkit-transform: perspective(400px) rotateY(0deg); + transform: perspective(400px) rotateY(0deg); + opacity: 1; + } +} + +@keyframes flipInY { + 0% { + -webkit-transform: perspective(400px) rotateY(90deg); + -ms-transform: perspective(400px) rotateY(90deg); + transform: perspective(400px) rotateY(90deg); + opacity: 0; + } + + 40% { + -webkit-transform: perspective(400px) rotateY(-10deg); + -ms-transform: perspective(400px) rotateY(-10deg); + transform: perspective(400px) rotateY(-10deg); + } + + 70% { + -webkit-transform: perspective(400px) rotateY(10deg); + -ms-transform: perspective(400px) rotateY(10deg); + transform: perspective(400px) rotateY(10deg); + } + + 100% { + -webkit-transform: perspective(400px) rotateY(0deg); + -ms-transform: perspective(400px) rotateY(0deg); + transform: perspective(400px) rotateY(0deg); + opacity: 1; + } +} + +.flipInY { + -webkit-backface-visibility: visible !important; + -ms-backface-visibility: visible !important; + backface-visibility: visible !important; + -webkit-animation-name: flipInY; + animation-name: flipInY; +} + +@-webkit-keyframes flipOutX { + 0% { + -webkit-transform: perspective(400px) rotateX(0deg); + transform: perspective(400px) rotateX(0deg); + opacity: 1; + } + + 100% { + -webkit-transform: perspective(400px) rotateX(90deg); + transform: perspective(400px) rotateX(90deg); + opacity: 0; + } +} + +@keyframes flipOutX { + 0% { + -webkit-transform: perspective(400px) rotateX(0deg); + -ms-transform: perspective(400px) rotateX(0deg); + transform: perspective(400px) rotateX(0deg); + opacity: 1; + } + + 100% { + -webkit-transform: perspective(400px) rotateX(90deg); + -ms-transform: perspective(400px) rotateX(90deg); + transform: perspective(400px) rotateX(90deg); + opacity: 0; + } +} + +.flipOutX { + -webkit-animation-name: flipOutX; + animation-name: flipOutX; + -webkit-backface-visibility: visible !important; + -ms-backface-visibility: visible !important; + backface-visibility: visible !important; +} + +@-webkit-keyframes flipOutY { + 0% { + -webkit-transform: perspective(400px) rotateY(0deg); + transform: perspective(400px) rotateY(0deg); + opacity: 1; + } + + 100% { + -webkit-transform: perspective(400px) rotateY(90deg); + transform: perspective(400px) rotateY(90deg); + opacity: 0; + } +} + +@keyframes flipOutY { + 0% { + -webkit-transform: perspective(400px) rotateY(0deg); + -ms-transform: perspective(400px) rotateY(0deg); + transform: perspective(400px) rotateY(0deg); + opacity: 1; + } + + 100% { + -webkit-transform: perspective(400px) rotateY(90deg); + -ms-transform: perspective(400px) rotateY(90deg); + transform: perspective(400px) rotateY(90deg); + opacity: 0; + } +} + +.flipOutY { + -webkit-backface-visibility: visible !important; + -ms-backface-visibility: visible !important; + backface-visibility: visible !important; + -webkit-animation-name: flipOutY; + animation-name: flipOutY; +} + +@-webkit-keyframes lightSpeedIn { + 0% { + -webkit-transform: translateX(100%) skewX(-30deg); + transform: translateX(100%) skewX(-30deg); + opacity: 0; + } + + 60% { + -webkit-transform: translateX(-20%) skewX(30deg); + transform: translateX(-20%) skewX(30deg); + opacity: 1; + } + + 80% { + -webkit-transform: translateX(0%) skewX(-15deg); + transform: translateX(0%) skewX(-15deg); + opacity: 1; + } + + 100% { + -webkit-transform: translateX(0%) skewX(0deg); + transform: translateX(0%) skewX(0deg); + opacity: 1; + } +} + +@keyframes lightSpeedIn { + 0% { + -webkit-transform: translateX(100%) skewX(-30deg); + -ms-transform: translateX(100%) skewX(-30deg); + transform: translateX(100%) skewX(-30deg); + opacity: 0; + } + + 60% { + -webkit-transform: translateX(-20%) skewX(30deg); + -ms-transform: translateX(-20%) skewX(30deg); + transform: translateX(-20%) skewX(30deg); + opacity: 1; + } + + 80% { + -webkit-transform: translateX(0%) skewX(-15deg); + -ms-transform: translateX(0%) skewX(-15deg); + transform: translateX(0%) skewX(-15deg); + opacity: 1; + } + + 100% { + -webkit-transform: translateX(0%) skewX(0deg); + -ms-transform: translateX(0%) skewX(0deg); + transform: translateX(0%) skewX(0deg); + opacity: 1; + } +} + +.lightSpeedIn { + -webkit-animation-name: lightSpeedIn; + animation-name: lightSpeedIn; + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; +} + +@-webkit-keyframes lightSpeedOut { + 0% { + -webkit-transform: translateX(0%) skewX(0deg); + transform: translateX(0%) skewX(0deg); + opacity: 1; + } + + 100% { + -webkit-transform: translateX(100%) skewX(-30deg); + transform: translateX(100%) skewX(-30deg); + opacity: 0; + } +} + +@keyframes lightSpeedOut { + 0% { + -webkit-transform: translateX(0%) skewX(0deg); + -ms-transform: translateX(0%) skewX(0deg); + transform: translateX(0%) skewX(0deg); + opacity: 1; + } + + 100% { + -webkit-transform: translateX(100%) skewX(-30deg); + -ms-transform: translateX(100%) skewX(-30deg); + transform: translateX(100%) skewX(-30deg); + opacity: 0; + } +} + +.lightSpeedOut { + -webkit-animation-name: lightSpeedOut; + animation-name: lightSpeedOut; + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; +} + +@-webkit-keyframes rotateIn { + 0% { + -webkit-transform-origin: center center; + transform-origin: center center; + -webkit-transform: rotate(-200deg); + transform: rotate(-200deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: center center; + transform-origin: center center; + -webkit-transform: rotate(0); + transform: rotate(0); + opacity: 1; + } +} + +@keyframes rotateIn { + 0% { + -webkit-transform-origin: center center; + -ms-transform-origin: center center; + transform-origin: center center; + -webkit-transform: rotate(-200deg); + -ms-transform: rotate(-200deg); + transform: rotate(-200deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: center center; + -ms-transform-origin: center center; + transform-origin: center center; + -webkit-transform: rotate(0); + -ms-transform: rotate(0); + transform: rotate(0); + opacity: 1; + } +} + +.rotateIn { + -webkit-animation-name: rotateIn; + animation-name: rotateIn; +} + +@-webkit-keyframes rotateInDownLeft { + 0% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate(-90deg); + transform: rotate(-90deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate(0); + transform: rotate(0); + opacity: 1; + } +} + +@keyframes rotateInDownLeft { + 0% { + -webkit-transform-origin: left bottom; + -ms-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate(-90deg); + -ms-transform: rotate(-90deg); + transform: rotate(-90deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: left bottom; + -ms-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate(0); + -ms-transform: rotate(0); + transform: rotate(0); + opacity: 1; + } +} + +.rotateInDownLeft { + -webkit-animation-name: rotateInDownLeft; + animation-name: rotateInDownLeft; +} + +@-webkit-keyframes rotateInDownRight { + 0% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate(90deg); + transform: rotate(90deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate(0); + transform: rotate(0); + opacity: 1; + } +} + +@keyframes rotateInDownRight { + 0% { + -webkit-transform-origin: right bottom; + -ms-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: right bottom; + -ms-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate(0); + -ms-transform: rotate(0); + transform: rotate(0); + opacity: 1; + } +} + +.rotateInDownRight { + -webkit-animation-name: rotateInDownRight; + animation-name: rotateInDownRight; +} + +@-webkit-keyframes rotateInUpLeft { + 0% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate(90deg); + transform: rotate(90deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate(0); + transform: rotate(0); + opacity: 1; + } +} + +@keyframes rotateInUpLeft { + 0% { + -webkit-transform-origin: left bottom; + -ms-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: left bottom; + -ms-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate(0); + -ms-transform: rotate(0); + transform: rotate(0); + opacity: 1; + } +} + +.rotateInUpLeft { + -webkit-animation-name: rotateInUpLeft; + animation-name: rotateInUpLeft; +} + +@-webkit-keyframes rotateInUpRight { + 0% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate(-90deg); + transform: rotate(-90deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate(0); + transform: rotate(0); + opacity: 1; + } +} + +@keyframes rotateInUpRight { + 0% { + -webkit-transform-origin: right bottom; + -ms-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate(-90deg); + -ms-transform: rotate(-90deg); + transform: rotate(-90deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: right bottom; + -ms-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate(0); + -ms-transform: rotate(0); + transform: rotate(0); + opacity: 1; + } +} + +.rotateInUpRight { + -webkit-animation-name: rotateInUpRight; + animation-name: rotateInUpRight; +} + +@-webkit-keyframes rotateOut { + 0% { + -webkit-transform-origin: center center; + transform-origin: center center; + -webkit-transform: rotate(0); + transform: rotate(0); + opacity: 1; + } + + 100% { + -webkit-transform-origin: center center; + transform-origin: center center; + -webkit-transform: rotate(200deg); + transform: rotate(200deg); + opacity: 0; + } +} + +@keyframes rotateOut { + 0% { + -webkit-transform-origin: center center; + -ms-transform-origin: center center; + transform-origin: center center; + -webkit-transform: rotate(0); + -ms-transform: rotate(0); + transform: rotate(0); + opacity: 1; + } + + 100% { + -webkit-transform-origin: center center; + -ms-transform-origin: center center; + transform-origin: center center; + -webkit-transform: rotate(200deg); + -ms-transform: rotate(200deg); + transform: rotate(200deg); + opacity: 0; + } +} + +.rotateOut { + -webkit-animation-name: rotateOut; + animation-name: rotateOut; +} + +@-webkit-keyframes rotateOutDownLeft { + 0% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate(0); + transform: rotate(0); + opacity: 1; + } + + 100% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate(90deg); + transform: rotate(90deg); + opacity: 0; + } +} + +@keyframes rotateOutDownLeft { + 0% { + -webkit-transform-origin: left bottom; + -ms-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate(0); + -ms-transform: rotate(0); + transform: rotate(0); + opacity: 1; + } + + 100% { + -webkit-transform-origin: left bottom; + -ms-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); + opacity: 0; + } +} + +.rotateOutDownLeft { + -webkit-animation-name: rotateOutDownLeft; + animation-name: rotateOutDownLeft; +} + +@-webkit-keyframes rotateOutDownRight { + 0% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate(0); + transform: rotate(0); + opacity: 1; + } + + 100% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate(-90deg); + transform: rotate(-90deg); + opacity: 0; + } +} + +@keyframes rotateOutDownRight { + 0% { + -webkit-transform-origin: right bottom; + -ms-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate(0); + -ms-transform: rotate(0); + transform: rotate(0); + opacity: 1; + } + + 100% { + -webkit-transform-origin: right bottom; + -ms-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate(-90deg); + -ms-transform: rotate(-90deg); + transform: rotate(-90deg); + opacity: 0; + } +} + +.rotateOutDownRight { + -webkit-animation-name: rotateOutDownRight; + animation-name: rotateOutDownRight; +} + +@-webkit-keyframes rotateOutUpLeft { + 0% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate(0); + transform: rotate(0); + opacity: 1; + } + + 100% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate(-90deg); + transform: rotate(-90deg); + opacity: 0; + } +} + +@keyframes rotateOutUpLeft { + 0% { + -webkit-transform-origin: left bottom; + -ms-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate(0); + -ms-transform: rotate(0); + transform: rotate(0); + opacity: 1; + } + + 100% { + -webkit-transform-origin: left bottom; + -ms-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate(-90deg); + -ms-transform: rotate(-90deg); + transform: rotate(-90deg); + opacity: 0; + } +} + +.rotateOutUpLeft { + -webkit-animation-name: rotateOutUpLeft; + animation-name: rotateOutUpLeft; +} + +@-webkit-keyframes rotateOutUpRight { + 0% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate(0); + transform: rotate(0); + opacity: 1; + } + + 100% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate(90deg); + transform: rotate(90deg); + opacity: 0; + } +} + +@keyframes rotateOutUpRight { + 0% { + -webkit-transform-origin: right bottom; + -ms-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate(0); + -ms-transform: rotate(0); + transform: rotate(0); + opacity: 1; + } + + 100% { + -webkit-transform-origin: right bottom; + -ms-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); + opacity: 0; + } +} + +.rotateOutUpRight { + -webkit-animation-name: rotateOutUpRight; + animation-name: rotateOutUpRight; +} + +@-webkit-keyframes slideInDown { + 0% { + opacity: 0; + -webkit-transform: translateY(-2000px); + transform: translateY(-2000px); + } + + 100% { + -webkit-transform: translateY(0); + transform: translateY(0); + } +} + +@keyframes slideInDown { + 0% { + opacity: 0; + -webkit-transform: translateY(-2000px); + -ms-transform: translateY(-2000px); + transform: translateY(-2000px); + } + + 100% { + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} + +.slideInDown { + -webkit-animation-name: slideInDown; + animation-name: slideInDown; +} + +@-webkit-keyframes slideInLeft { + 0% { + opacity: 0; + -webkit-transform: translateX(-2000px); + transform: translateX(-2000px); + } + + 100% { + -webkit-transform: translateX(0); + transform: translateX(0); + } +} + +@keyframes slideInLeft { + 0% { + opacity: 0; + -webkit-transform: translateX(-2000px); + -ms-transform: translateX(-2000px); + transform: translateX(-2000px); + } + + 100% { + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } +} + +.slideInLeft { + -webkit-animation-name: slideInLeft; + animation-name: slideInLeft; +} + +@-webkit-keyframes slideInRight { + 0% { + opacity: 0; + -webkit-transform: translateX(2000px); + transform: translateX(2000px); + } + + 100% { + -webkit-transform: translateX(0); + transform: translateX(0); + } +} + +@keyframes slideInRight { + 0% { + opacity: 0; + -webkit-transform: translateX(2000px); + -ms-transform: translateX(2000px); + transform: translateX(2000px); + } + + 100% { + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } +} + +.slideInRight { + -webkit-animation-name: slideInRight; + animation-name: slideInRight; +} + +@-webkit-keyframes slideOutLeft { + 0% { + -webkit-transform: translateX(0); + transform: translateX(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(-2000px); + transform: translateX(-2000px); + } +} + +@keyframes slideOutLeft { + 0% { + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(-2000px); + -ms-transform: translateX(-2000px); + transform: translateX(-2000px); + } +} + +.slideOutLeft { + -webkit-animation-name: slideOutLeft; + animation-name: slideOutLeft; +} + +@-webkit-keyframes slideOutRight { + 0% { + -webkit-transform: translateX(0); + transform: translateX(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(2000px); + transform: translateX(2000px); + } +} + +@keyframes slideOutRight { + 0% { + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(2000px); + -ms-transform: translateX(2000px); + transform: translateX(2000px); + } +} + +.slideOutRight { + -webkit-animation-name: slideOutRight; + animation-name: slideOutRight; +} + +@-webkit-keyframes slideOutUp { + 0% { + -webkit-transform: translateY(0); + transform: translateY(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(-2000px); + transform: translateY(-2000px); + } +} + +@keyframes slideOutUp { + 0% { + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(-2000px); + -ms-transform: translateY(-2000px); + transform: translateY(-2000px); + } +} + +.slideOutUp { + -webkit-animation-name: slideOutUp; + animation-name: slideOutUp; +} + +@-webkit-keyframes hinge { + 0% { + -webkit-transform: rotate(0); + transform: rotate(0); + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 20%, 60% { + -webkit-transform: rotate(80deg); + transform: rotate(80deg); + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 40% { + -webkit-transform: rotate(60deg); + transform: rotate(60deg); + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 80% { + -webkit-transform: rotate(60deg) translateY(0); + transform: rotate(60deg) translateY(0); + opacity: 1; + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 100% { + -webkit-transform: translateY(700px); + transform: translateY(700px); + opacity: 0; + } +} + +@keyframes hinge { + 0% { + -webkit-transform: rotate(0); + -ms-transform: rotate(0); + transform: rotate(0); + -webkit-transform-origin: top left; + -ms-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 20%, 60% { + -webkit-transform: rotate(80deg); + -ms-transform: rotate(80deg); + transform: rotate(80deg); + -webkit-transform-origin: top left; + -ms-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 40% { + -webkit-transform: rotate(60deg); + -ms-transform: rotate(60deg); + transform: rotate(60deg); + -webkit-transform-origin: top left; + -ms-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 80% { + -webkit-transform: rotate(60deg) translateY(0); + -ms-transform: rotate(60deg) translateY(0); + transform: rotate(60deg) translateY(0); + opacity: 1; + -webkit-transform-origin: top left; + -ms-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 100% { + -webkit-transform: translateY(700px); + -ms-transform: translateY(700px); + transform: translateY(700px); + opacity: 0; + } +} + +.hinge { + -webkit-animation-name: hinge; + animation-name: hinge; +} + +/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ + +@-webkit-keyframes rollIn { + 0% { + opacity: 0; + -webkit-transform: translateX(-100%) rotate(-120deg); + transform: translateX(-100%) rotate(-120deg); + } + + 100% { + opacity: 1; + -webkit-transform: translateX(0px) rotate(0deg); + transform: translateX(0px) rotate(0deg); + } +} + +@keyframes rollIn { + 0% { + opacity: 0; + -webkit-transform: translateX(-100%) rotate(-120deg); + -ms-transform: translateX(-100%) rotate(-120deg); + transform: translateX(-100%) rotate(-120deg); + } + + 100% { + opacity: 1; + -webkit-transform: translateX(0px) rotate(0deg); + -ms-transform: translateX(0px) rotate(0deg); + transform: translateX(0px) rotate(0deg); + } +} + +.rollIn { + -webkit-animation-name: rollIn; + animation-name: rollIn; +} + +/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ + +@-webkit-keyframes rollOut { + 0% { + opacity: 1; + -webkit-transform: translateX(0px) rotate(0deg); + transform: translateX(0px) rotate(0deg); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(100%) rotate(120deg); + transform: translateX(100%) rotate(120deg); + } +} + +@keyframes rollOut { + 0% { + opacity: 1; + -webkit-transform: translateX(0px) rotate(0deg); + -ms-transform: translateX(0px) rotate(0deg); + transform: translateX(0px) rotate(0deg); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(100%) rotate(120deg); + -ms-transform: translateX(100%) rotate(120deg); + transform: translateX(100%) rotate(120deg); + } +} + +.rollOut { + -webkit-animation-name: rollOut; + animation-name: rollOut; } \ No newline at end of file diff --git a/webgoat-container/src/main/webapp/css/font-awesome.min.css b/webgoat-container/src/main/resources/static/css/font-awesome.min.css similarity index 100% rename from webgoat-container/src/main/webapp/css/font-awesome.min.css rename to webgoat-container/src/main/resources/static/css/font-awesome.min.css diff --git a/webgoat-container/src/main/webapp/css/img/logo.png b/webgoat-container/src/main/resources/static/css/img/logo.png similarity index 100% rename from webgoat-container/src/main/webapp/css/img/logo.png rename to webgoat-container/src/main/resources/static/css/img/logo.png diff --git a/webgoat-container/src/main/webapp/css/img/logoBG.jpg b/webgoat-container/src/main/resources/static/css/img/logoBG.jpg similarity index 100% rename from webgoat-container/src/main/webapp/css/img/logoBG.jpg rename to webgoat-container/src/main/resources/static/css/img/logoBG.jpg diff --git a/webgoat-container/src/main/webapp/css/img/webBg.png b/webgoat-container/src/main/resources/static/css/img/webBg.png similarity index 100% rename from webgoat-container/src/main/webapp/css/img/webBg.png rename to webgoat-container/src/main/resources/static/css/img/webBg.png diff --git a/webgoat-container/src/main/webapp/css/layers.css b/webgoat-container/src/main/resources/static/css/layers.css similarity index 99% rename from webgoat-container/src/main/webapp/css/layers.css rename to webgoat-container/src/main/resources/static/css/layers.css index 99d09863f..a5081db2b 100644 --- a/webgoat-container/src/main/webapp/css/layers.css +++ b/webgoat-container/src/main/resources/static/css/layers.css @@ -1,2 +1,2 @@ -#lesson-title {position:absolute;left:94px;top:75px;width:690px;height:22px;z-index:1;float: right;font-size: 20px;color: #FFFFFF;} -#hMenuBar {position:absolute;left:245px;top:108px;width:538px;height:22px;z-index:2;} +#lesson-title {position:absolute;left:94px;top:75px;width:690px;height:22px;z-index:1;float: right;font-size: 20px;color: #FFFFFF;} +#hMenuBar {position:absolute;left:245px;top:108px;width:538px;height:22px;z-index:2;} diff --git a/webgoat-container/src/main/webapp/css/lesson.css b/webgoat-container/src/main/resources/static/css/lesson.css similarity index 98% rename from webgoat-container/src/main/webapp/css/lesson.css rename to webgoat-container/src/main/resources/static/css/lesson.css index ba0229b96..06174eecd 100644 --- a/webgoat-container/src/main/webapp/css/lesson.css +++ b/webgoat-container/src/main/resources/static/css/lesson.css @@ -1,11 +1,11 @@ -body.page {color: #000000;font-family: Verdana, Tahoma, sans-serif;font-size: 8pt;} -td {font-family: Verdana, Tahoma, sans-serif;font-size: 8pt; } -tr {font-family: Verdana, Tahoma, sans-serif;} -span {font-family: Verdana, Tahoma, sans-serif;} -.f8-0 {font-size: 8pt;font-family: Verdana, Tahoma, sans-serif;} -.f8-1 {font-size: 8pt;font-family: Verdana, Tahoma, sans-serif;} -.div_tree {padding-left:10px;overflow:visible;} -.report_tree_link {width:100%;font-size: 8pt;font-family: Verdana, Tahoma, sans-serif;margin-left:2px;padding-right:2px;margin-top:2px;border-spacing:0px;} -.form_link {font-size: 8pt;font-family: Verdana, Tahoma, sans-serif;font-weight: bold;} -.report_title {font-size: 8pt;font-family: Verdana, Tahoma, sans-serif;border: 1px solid #afafaf;background-color: #cfcfef;margin-top:3px;margin-bottom:3px;margin-left:1px;padding:3px;font-weight: bold;} +body.page {color: #000000;font-family: Verdana, Tahoma, sans-serif;font-size: 8pt;} +td {font-family: Verdana, Tahoma, sans-serif;font-size: 8pt; } +tr {font-family: Verdana, Tahoma, sans-serif;} +span {font-family: Verdana, Tahoma, sans-serif;} +.f8-0 {font-size: 8pt;font-family: Verdana, Tahoma, sans-serif;} +.f8-1 {font-size: 8pt;font-family: Verdana, Tahoma, sans-serif;} +.div_tree {padding-left:10px;overflow:visible;} +.report_tree_link {width:100%;font-size: 8pt;font-family: Verdana, Tahoma, sans-serif;margin-left:2px;padding-right:2px;margin-top:2px;border-spacing:0px;} +.form_link {font-size: 8pt;font-family: Verdana, Tahoma, sans-serif;font-weight: bold;} +.report_title {font-size: 8pt;font-family: Verdana, Tahoma, sans-serif;border: 1px solid #afafaf;background-color: #cfcfef;margin-top:3px;margin-bottom:3px;margin-left:1px;padding:3px;font-weight: bold;} .middle {vertical-align:middle;} \ No newline at end of file diff --git a/webgoat-container/src/main/webapp/css/main.css b/webgoat-container/src/main/resources/static/css/main.css similarity index 100% rename from webgoat-container/src/main/webapp/css/main.css rename to webgoat-container/src/main/resources/static/css/main.css diff --git a/webgoat-container/src/main/webapp/css/menu.css b/webgoat-container/src/main/resources/static/css/menu.css similarity index 98% rename from webgoat-container/src/main/webapp/css/menu.css rename to webgoat-container/src/main/resources/static/css/menu.css index 0436f5aeb..93b4aa59b 100644 --- a/webgoat-container/src/main/webapp/css/menu.css +++ b/webgoat-container/src/main/resources/static/css/menu.css @@ -1,11 +1,11 @@ -.pviimenudiv td {font-family: "Trebuchet MS", Arial, sans-serif; font-size: 10px} -.pviimenudiv p {font-family: "Trebuchet MS", Arial, sans-serif; font-size: 10px; margin-top: 12px; margin-bottom: 6px} -.pviimenudiv b {font-family: Verdana, Arial, Helvetica, sans-serif; font-style: normal; color: #666666} -.pviimenudiv a:link {color: #333333; text-decoration: underline} -.pviimenudiv a:visited {color: #0066FF; text-decoration: underline} -.pviimenudiv a:hover {color: red; text-decoration: underline} -.pviimenudiv a:active {color: #0066FF; text-decoration: underline} -.pviimenudivstage a:link {color: #333333; font-size: 9px; display: block; margin-left: 2em; } -.pviimenudivstage a:visited {color: #0066FF; font-size: 9px; display: block; margin-left: 2em; } -.pviimenudivstage a:hover {color: red; font-size: 9px; display: block; margin-left: 2em; } -.pviimenudivstage a:active {color: #0066FF; font-size: 9px; display: block; margin-left: 2em; } +.pviimenudiv td {font-family: "Trebuchet MS", Arial, sans-serif; font-size: 10px} +.pviimenudiv p {font-family: "Trebuchet MS", Arial, sans-serif; font-size: 10px; margin-top: 12px; margin-bottom: 6px} +.pviimenudiv b {font-family: Verdana, Arial, Helvetica, sans-serif; font-style: normal; color: #666666} +.pviimenudiv a:link {color: #333333; text-decoration: underline} +.pviimenudiv a:visited {color: #0066FF; text-decoration: underline} +.pviimenudiv a:hover {color: red; text-decoration: underline} +.pviimenudiv a:active {color: #0066FF; text-decoration: underline} +.pviimenudivstage a:link {color: #333333; font-size: 9px; display: block; margin-left: 2em; } +.pviimenudivstage a:visited {color: #0066FF; font-size: 9px; display: block; margin-left: 2em; } +.pviimenudivstage a:hover {color: red; font-size: 9px; display: block; margin-left: 2em; } +.pviimenudivstage a:active {color: #0066FF; font-size: 9px; display: block; margin-left: 2em; } diff --git a/webgoat-container/src/main/webapp/css/webgoat.css b/webgoat-container/src/main/resources/static/css/webgoat.css similarity index 92% rename from webgoat-container/src/main/webapp/css/webgoat.css rename to webgoat-container/src/main/resources/static/css/webgoat.css index dd61f086b..7c66701ab 100644 --- a/webgoat-container/src/main/webapp/css/webgoat.css +++ b/webgoat-container/src/main/resources/static/css/webgoat.css @@ -1,305 +1,305 @@ -/* -body{ - min-width: 800px; - font-family: Arial,sans-serif; - color: #333333; - line-height: 1.166; - margin: 0px; - padding: 0px; -} - -a:link, a:visited, a:hover { - color: #666666; - text-decoration: none; -} - -a:hover { - text-decoration: underline; - color: red; -} - -h1, h2, h3, h4, h5, h6 { - font-family: Arial,sans-serif; - margin: 0px; - padding: 0px; -} - -h1{ - font-family: Verdana,Arial,sans-serif; - font-size: 120%; - color: #333333; -} - -h2{ - font-size: 114%; - color: #333333; -} - -h3{ - font-size: 100%; - color: #334d55; -} - -h4{ - font-size: 100%; - font-weight: normal; - color: #333333; -} - -h5{ - font-size: 100%; - color: #334d55; -} -*/ -ul{ - list-style-type: square; -} - -ul ul{ - list-style-type: disc; -} - -ul ul ul{ - list-style-type: none; -} - -#navBar{ - margin: 0 79% 0 0; - padding: 0px; - background-color: #999999; -} - -#twoCol{ - margin: 0; - padding-left: 13px; -} - -#siteName{ - margin: 0px; - padding: 0px 0px 10px 10px; -} - -#lessonName{ - padding: 5px 0px 10px 10px; -} - -#globalNav{ - color: #cccccc; - padding: 0px 10px; - white-space: nowrap; -} - -#globalNav img{ - display: block; -} - -#globalNav a { - font-size: 10px; - padding: 0px 4px 0px 0px; -} - -.lessonContent{ - padding: 10px 10px 10px 10px; - font-size: 10px; -} - -.lessonText h3{ - padding: 30px 0px 5px 0px; - text-align: center; -} - -.lessonText img{ - float: left; - padding: 0px 10px 0px 0px; - margin: 0 5px 5px 0; -} - -#bottom{ - color: #999999; - clear: both; - font-size: 10px; - padding-top: 5px; -} - -#navBar ul a:link, #navBar ul a:visited {} - -#navBar ul { - list-style: none; - margin: 0; - padding: 0; -} - -/* hack to fix IE/Win's broken rendering of block-level anchors in lists */ -#navBar li {} - -/* fix for browsers that don't need the hack */ -html>body #navBar li {} - -#top{ - height:136px; - background-image: url(img/header/header.jpg); - width: 800px; -} - -#top_challenge{ - height:136px; - width: 800px; -} - -#topLinks{ - position: relative; - margin: 0px; - padding: 0px; - font-size: small; -} - -#topLinks h3{ - padding: 10px 0px 2px 10px; -} - -#topLinks a:link{ - padding: 2px 0px 2px 10px; - width: 100%; - voice-family:inherit; - width: auto; -} - -#topLinks a:visited{ - border-top: 1px solid #cccccc; - padding: 2px 0px 2px 10px; -} - -#topLinks a:hover{ - background-color: #FFFFFF; - padding: 5px 2px 2px 10px; -} - -#menuSpacer { - float: left; - width: 225px; -} - -#lessonArea { - float: right; - width: 540px; - height: 100%; - padding: 10px; -} -#lessonAreaTop { - float: right; - width: 540px; - height: 15px; - padding: 10px; -} - -#wrap { - width: 800px; - word-wrap:break-word; /* Fixes IE wrapping issue */ -} - -#topRight { - position:absolute; - left:380px; - top:0px; - width:400px; - height:23px; - z-index:3; - float: right; -} - -#topLeft { - position:absolute; - left:100px; - top:0px; - width:400px; - height:23px; - z-index:3; - float: right; -} -#topRightInner { - position:absolute; - left:450px; - top:10px; - width:300px; - height:23px; - z-index:4; - float: right; -} - -.info { - color: red; - font-weight: bold; -} - -#reset { - text-align: right; - font-weight: bold; - float: right; - display: inline; - margin-bottom: 10px; -} - -#training { - text-align: left; - font-weight: bold; - display: inline; - float: left; - margin-bottom: 10px; - -} - -#training_wrap { - width: 540px; -} - -#hint{} -#parameter{} -#cookie{} -#message{ - margin-bottom: 20px; - margin-top: 10px; -} - -#lessonPlans { - border: 1px solid #000000; - background-color: #FFFFFF; - margin: 15px; - padding: 25px; - padding-bottom: 75px; -} - -#credits { - float: right; -} - -#start { - height: 370px; - width: 700px; - padding: 10px 50px 10px 50px; - font-size: 15px; -} -#warning { - border: 1px solid #666666; - padding: 10px; - font-size: 10px; - color: #FF3300; - width: 600px; - margin-left: 100px; - margin-right: 100px; -} -#team { - width: 580px; - margin-right: 50px; - margin-left: 50px; - padding-top: 5px; - padding-right: 10px; - padding-bottom: 5px; - padding-left: 10px; -} -.style1 { - font-size: 11px; - font-weight: bold; -} -.style2 { - font-size: 10px; -} +/* +body{ + min-width: 800px; + font-family: Arial,sans-serif; + color: #333333; + line-height: 1.166; + margin: 0px; + padding: 0px; +} + +a:link, a:visited, a:hover { + color: #666666; + text-decoration: none; +} + +a:hover { + text-decoration: underline; + color: red; +} + +h1, h2, h3, h4, h5, h6 { + font-family: Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +h1{ + font-family: Verdana,Arial,sans-serif; + font-size: 120%; + color: #333333; +} + +h2{ + font-size: 114%; + color: #333333; +} + +h3{ + font-size: 100%; + color: #334d55; +} + +h4{ + font-size: 100%; + font-weight: normal; + color: #333333; +} + +h5{ + font-size: 100%; + color: #334d55; +} +*/ +ul{ + list-style-type: square; +} + +ul ul{ + list-style-type: disc; +} + +ul ul ul{ + list-style-type: none; +} + +#navBar{ + margin: 0 79% 0 0; + padding: 0px; + background-color: #999999; +} + +#twoCol{ + margin: 0; + padding-left: 13px; +} + +#siteName{ + margin: 0px; + padding: 0px 0px 10px 10px; +} + +#lessonName{ + padding: 5px 0px 10px 10px; +} + +#globalNav{ + color: #cccccc; + padding: 0px 10px; + white-space: nowrap; +} + +#globalNav img{ + display: block; +} + +#globalNav a { + font-size: 10px; + padding: 0px 4px 0px 0px; +} + +.lessonContent{ + padding: 10px 10px 10px 10px; + font-size: 10px; +} + +.lessonText h3{ + padding: 30px 0px 5px 0px; + text-align: center; +} + +.lessonText img{ + float: left; + padding: 0px 10px 0px 0px; + margin: 0 5px 5px 0; +} + +#bottom{ + color: #999999; + clear: both; + font-size: 10px; + padding-top: 5px; +} + +#navBar ul a:link, #navBar ul a:visited {} + +#navBar ul { + list-style: none; + margin: 0; + padding: 0; +} + +/* hack to fix IE/Win's broken rendering of block-level anchors in lists */ +#navBar li {} + +/* fix for browsers that don't need the hack */ +html>body #navBar li {} + +#top{ + height:136px; + background-image: url(img/header/header.jpg); + width: 800px; +} + +#top_challenge{ + height:136px; + width: 800px; +} + +#topLinks{ + position: relative; + margin: 0px; + padding: 0px; + font-size: small; +} + +#topLinks h3{ + padding: 10px 0px 2px 10px; +} + +#topLinks a:link{ + padding: 2px 0px 2px 10px; + width: 100%; + voice-family:inherit; + width: auto; +} + +#topLinks a:visited{ + border-top: 1px solid #cccccc; + padding: 2px 0px 2px 10px; +} + +#topLinks a:hover{ + background-color: #FFFFFF; + padding: 5px 2px 2px 10px; +} + +#menuSpacer { + float: left; + width: 225px; +} + +#lessonArea { + float: right; + width: 540px; + height: 100%; + padding: 10px; +} +#lessonAreaTop { + float: right; + width: 540px; + height: 15px; + padding: 10px; +} + +#wrap { + width: 800px; + word-wrap:break-word; /* Fixes IE wrapping issue */ +} + +#topRight { + position:absolute; + left:380px; + top:0px; + width:400px; + height:23px; + z-index:3; + float: right; +} + +#topLeft { + position:absolute; + left:100px; + top:0px; + width:400px; + height:23px; + z-index:3; + float: right; +} +#topRightInner { + position:absolute; + left:450px; + top:10px; + width:300px; + height:23px; + z-index:4; + float: right; +} + +.info { + color: red; + font-weight: bold; +} + +#reset { + text-align: right; + font-weight: bold; + float: right; + display: inline; + margin-bottom: 10px; +} + +#training { + text-align: left; + font-weight: bold; + display: inline; + float: left; + margin-bottom: 10px; + +} + +#training_wrap { + width: 540px; +} + +#hint{} +#parameter{} +#cookie{} +#message{ + margin-bottom: 20px; + margin-top: 10px; +} + +#lessonPlans { + border: 1px solid #000000; + background-color: #FFFFFF; + margin: 15px; + padding: 25px; + padding-bottom: 75px; +} + +#credits { + float: right; +} + +#start { + height: 370px; + width: 700px; + padding: 10px 50px 10px 50px; + font-size: 15px; +} +#warning { + border: 1px solid #666666; + padding: 10px; + font-size: 10px; + color: #FF3300; + width: 600px; + margin-left: 100px; + margin-right: 100px; +} +#team { + width: 580px; + margin-right: 50px; + margin-left: 50px; + padding-top: 5px; + padding-right: 10px; + padding-bottom: 5px; + padding-left: 10px; +} +.style1 { + font-size: 11px; + font-weight: bold; +} +.style2 { + font-size: 10px; +} diff --git a/webgoat-container/src/main/webapp/fonts/FontAwesome.otf b/webgoat-container/src/main/resources/static/fonts/FontAwesome.otf similarity index 100% rename from webgoat-container/src/main/webapp/fonts/FontAwesome.otf rename to webgoat-container/src/main/resources/static/fonts/FontAwesome.otf diff --git a/webgoat-container/src/main/webapp/fonts/fontawesome-webfont.eot b/webgoat-container/src/main/resources/static/fonts/fontawesome-webfont.eot similarity index 100% rename from webgoat-container/src/main/webapp/fonts/fontawesome-webfont.eot rename to webgoat-container/src/main/resources/static/fonts/fontawesome-webfont.eot diff --git a/webgoat-container/src/main/webapp/fonts/fontawesome-webfont.svg b/webgoat-container/src/main/resources/static/fonts/fontawesome-webfont.svg similarity index 100% rename from webgoat-container/src/main/webapp/fonts/fontawesome-webfont.svg rename to webgoat-container/src/main/resources/static/fonts/fontawesome-webfont.svg diff --git a/webgoat-container/src/main/webapp/fonts/fontawesome-webfont.ttf b/webgoat-container/src/main/resources/static/fonts/fontawesome-webfont.ttf similarity index 100% rename from webgoat-container/src/main/webapp/fonts/fontawesome-webfont.ttf rename to webgoat-container/src/main/resources/static/fonts/fontawesome-webfont.ttf diff --git a/webgoat-container/src/main/webapp/fonts/fontawesome-webfont.woff b/webgoat-container/src/main/resources/static/fonts/fontawesome-webfont.woff similarity index 100% rename from webgoat-container/src/main/webapp/fonts/fontawesome-webfont.woff rename to webgoat-container/src/main/resources/static/fonts/fontawesome-webfont.woff diff --git a/webgoat-container/src/main/webapp/images/WebGoatFinancial/banklogo.jpg b/webgoat-container/src/main/resources/static/images/WebGoatFinancial/banklogo.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/WebGoatFinancial/banklogo.jpg rename to webgoat-container/src/main/resources/static/images/WebGoatFinancial/banklogo.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/catStarted.jpg b/webgoat-container/src/main/resources/static/images/buttons/catStarted.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/catStarted.jpg rename to webgoat-container/src/main/resources/static/images/buttons/catStarted.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/cookies.jpg b/webgoat-container/src/main/resources/static/images/buttons/cookies.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/cookies.jpg rename to webgoat-container/src/main/resources/static/images/buttons/cookies.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/cookiesOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/cookiesOver.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/cookiesOver.jpg rename to webgoat-container/src/main/resources/static/images/buttons/cookiesOver.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/help.jpg b/webgoat-container/src/main/resources/static/images/buttons/help.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/help.jpg rename to webgoat-container/src/main/resources/static/images/buttons/help.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/helpOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/helpOver.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/helpOver.jpg rename to webgoat-container/src/main/resources/static/images/buttons/helpOver.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/hint.jpg b/webgoat-container/src/main/resources/static/images/buttons/hint.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/hint.jpg rename to webgoat-container/src/main/resources/static/images/buttons/hint.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/hintLeft.jpg b/webgoat-container/src/main/resources/static/images/buttons/hintLeft.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/hintLeft.jpg rename to webgoat-container/src/main/resources/static/images/buttons/hintLeft.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/hintLeftOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/hintLeftOver.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/hintLeftOver.jpg rename to webgoat-container/src/main/resources/static/images/buttons/hintLeftOver.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/hintOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/hintOver.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/hintOver.jpg rename to webgoat-container/src/main/resources/static/images/buttons/hintOver.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/hintRight.jpg b/webgoat-container/src/main/resources/static/images/buttons/hintRight.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/hintRight.jpg rename to webgoat-container/src/main/resources/static/images/buttons/hintRight.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/hintRightOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/hintRightOver.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/hintRightOver.jpg rename to webgoat-container/src/main/resources/static/images/buttons/hintRightOver.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/html.jpg b/webgoat-container/src/main/resources/static/images/buttons/html.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/html.jpg rename to webgoat-container/src/main/resources/static/images/buttons/html.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/htmlOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/htmlOver.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/htmlOver.jpg rename to webgoat-container/src/main/resources/static/images/buttons/htmlOver.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/java.jpg b/webgoat-container/src/main/resources/static/images/buttons/java.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/java.jpg rename to webgoat-container/src/main/resources/static/images/buttons/java.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/javaOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/javaOver.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/javaOver.jpg rename to webgoat-container/src/main/resources/static/images/buttons/javaOver.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/lessonComplete.jpg b/webgoat-container/src/main/resources/static/images/buttons/lessonComplete.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/lessonComplete.jpg rename to webgoat-container/src/main/resources/static/images/buttons/lessonComplete.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/logout.jpg b/webgoat-container/src/main/resources/static/images/buttons/logout.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/logout.jpg rename to webgoat-container/src/main/resources/static/images/buttons/logout.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/logoutOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/logoutOver.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/logoutOver.jpg rename to webgoat-container/src/main/resources/static/images/buttons/logoutOver.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/params.jpg b/webgoat-container/src/main/resources/static/images/buttons/params.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/params.jpg rename to webgoat-container/src/main/resources/static/images/buttons/params.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/paramsOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/paramsOver.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/paramsOver.jpg rename to webgoat-container/src/main/resources/static/images/buttons/paramsOver.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/plans.jpg b/webgoat-container/src/main/resources/static/images/buttons/plans.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/plans.jpg rename to webgoat-container/src/main/resources/static/images/buttons/plans.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/plansOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/plansOver.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/plansOver.jpg rename to webgoat-container/src/main/resources/static/images/buttons/plansOver.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/solutions.jpg b/webgoat-container/src/main/resources/static/images/buttons/solutions.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/solutions.jpg rename to webgoat-container/src/main/resources/static/images/buttons/solutions.jpg diff --git a/webgoat-container/src/main/webapp/images/buttons/solutionsOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/solutionsOver.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/buttons/solutionsOver.jpg rename to webgoat-container/src/main/resources/static/images/buttons/solutionsOver.jpg diff --git a/webgoat-container/src/main/webapp/images/header/header.jpg b/webgoat-container/src/main/resources/static/images/header/header.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/header/header.jpg rename to webgoat-container/src/main/resources/static/images/header/header.jpg diff --git a/webgoat-container/src/main/webapp/images/header/header_ASP.jpg b/webgoat-container/src/main/resources/static/images/header/header_ASP.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/header/header_ASP.jpg rename to webgoat-container/src/main/resources/static/images/header/header_ASP.jpg diff --git a/webgoat-container/src/main/webapp/images/header/header_CShrp.jpg b/webgoat-container/src/main/resources/static/images/header/header_CShrp.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/header/header_CShrp.jpg rename to webgoat-container/src/main/resources/static/images/header/header_CShrp.jpg diff --git a/webgoat-container/src/main/webapp/images/header/header_coldFusion.jpg b/webgoat-container/src/main/resources/static/images/header/header_coldFusion.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/header/header_coldFusion.jpg rename to webgoat-container/src/main/resources/static/images/header/header_coldFusion.jpg diff --git a/webgoat-container/src/main/webapp/images/header/header_dotNet.jpg b/webgoat-container/src/main/resources/static/images/header/header_dotNet.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/header/header_dotNet.jpg rename to webgoat-container/src/main/resources/static/images/header/header_dotNet.jpg diff --git a/webgoat-container/src/main/webapp/images/icons/rightArrow.jpg b/webgoat-container/src/main/resources/static/images/icons/rightArrow.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/icons/rightArrow.jpg rename to webgoat-container/src/main/resources/static/images/icons/rightArrow.jpg diff --git a/webgoat-container/src/main/webapp/images/introduction/HowToUse_2.jpg b/webgoat-container/src/main/resources/static/images/introduction/HowToUse_2.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/introduction/HowToUse_2.jpg rename to webgoat-container/src/main/resources/static/images/introduction/HowToUse_2.jpg diff --git a/webgoat-container/src/main/webapp/images/introduction/HowToUse_3.jpg b/webgoat-container/src/main/resources/static/images/introduction/HowToUse_3.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/introduction/HowToUse_3.jpg rename to webgoat-container/src/main/resources/static/images/introduction/HowToUse_3.jpg diff --git a/webgoat-container/src/main/webapp/images/introduction/UsefulTools-ZAP.png b/webgoat-container/src/main/resources/static/images/introduction/UsefulTools-ZAP.png similarity index 100% rename from webgoat-container/src/main/webapp/images/introduction/UsefulTools-ZAP.png rename to webgoat-container/src/main/resources/static/images/introduction/UsefulTools-ZAP.png diff --git a/webgoat-container/src/main/webapp/images/introduction/UsefulTools-ZAP_1.png b/webgoat-container/src/main/resources/static/images/introduction/UsefulTools-ZAP_1.png similarity index 100% rename from webgoat-container/src/main/webapp/images/introduction/UsefulTools-ZAP_1.png rename to webgoat-container/src/main/resources/static/images/introduction/UsefulTools-ZAP_1.png diff --git a/webgoat-container/src/main/webapp/images/introduction/interface.png b/webgoat-container/src/main/resources/static/images/introduction/interface.png similarity index 100% rename from webgoat-container/src/main/webapp/images/introduction/interface.png rename to webgoat-container/src/main/resources/static/images/introduction/interface.png diff --git a/webgoat-container/src/main/webapp/images/introduction/wireshark.png b/webgoat-container/src/main/resources/static/images/introduction/wireshark.png similarity index 100% rename from webgoat-container/src/main/webapp/images/introduction/wireshark.png rename to webgoat-container/src/main/resources/static/images/introduction/wireshark.png diff --git a/webgoat-container/src/main/webapp/images/logo.png b/webgoat-container/src/main/resources/static/images/logo.png similarity index 100% rename from webgoat-container/src/main/webapp/images/logo.png rename to webgoat-container/src/main/resources/static/images/logo.png diff --git a/webgoat-container/src/main/webapp/images/logos/aspect.jpg b/webgoat-container/src/main/resources/static/images/logos/aspect.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/logos/aspect.jpg rename to webgoat-container/src/main/resources/static/images/logos/aspect.jpg diff --git a/webgoat-container/src/main/webapp/images/logos/macadamian.gif b/webgoat-container/src/main/resources/static/images/logos/macadamian.gif similarity index 100% rename from webgoat-container/src/main/webapp/images/logos/macadamian.gif rename to webgoat-container/src/main/resources/static/images/logos/macadamian.gif diff --git a/webgoat-container/src/main/webapp/images/logos/mandiant.png b/webgoat-container/src/main/resources/static/images/logos/mandiant.png similarity index 100% rename from webgoat-container/src/main/webapp/images/logos/mandiant.png rename to webgoat-container/src/main/resources/static/images/logos/mandiant.png diff --git a/webgoat-container/src/main/webapp/images/logos/ounce.jpg b/webgoat-container/src/main/resources/static/images/logos/ounce.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/logos/ounce.jpg rename to webgoat-container/src/main/resources/static/images/logos/ounce.jpg diff --git a/webgoat-container/src/main/webapp/images/logos/owasp.jpg b/webgoat-container/src/main/resources/static/images/logos/owasp.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/logos/owasp.jpg rename to webgoat-container/src/main/resources/static/images/logos/owasp.jpg diff --git a/webgoat-container/src/main/webapp/images/logos/parasoft.jpg b/webgoat-container/src/main/resources/static/images/logos/parasoft.jpg similarity index 100% rename from webgoat-container/src/main/webapp/images/logos/parasoft.jpg rename to webgoat-container/src/main/resources/static/images/logos/parasoft.jpg diff --git a/webgoat-container/src/main/webapp/images/logos/sages.png b/webgoat-container/src/main/resources/static/images/logos/sages.png similarity index 100% rename from webgoat-container/src/main/webapp/images/logos/sages.png rename to webgoat-container/src/main/resources/static/images/logos/sages.png diff --git a/webgoat-container/src/main/webapp/images/logos/seleucus.png b/webgoat-container/src/main/resources/static/images/logos/seleucus.png similarity index 100% rename from webgoat-container/src/main/webapp/images/logos/seleucus.png rename to webgoat-container/src/main/resources/static/images/logos/seleucus.png diff --git a/webgoat-container/src/main/webapp/images/logos/softwaresecured.gif b/webgoat-container/src/main/resources/static/images/logos/softwaresecured.gif similarity index 100% rename from webgoat-container/src/main/webapp/images/logos/softwaresecured.gif rename to webgoat-container/src/main/resources/static/images/logos/softwaresecured.gif diff --git a/webgoat-container/src/main/webapp/images/logos/zionsecurity.gif b/webgoat-container/src/main/resources/static/images/logos/zionsecurity.gif similarity index 100% rename from webgoat-container/src/main/webapp/images/logos/zionsecurity.gif rename to webgoat-container/src/main/resources/static/images/logos/zionsecurity.gif diff --git a/webgoat-container/src/main/webapp/images/menu_images/1x1.gif b/webgoat-container/src/main/resources/static/images/menu_images/1x1.gif similarity index 100% rename from webgoat-container/src/main/webapp/images/menu_images/1x1.gif rename to webgoat-container/src/main/resources/static/images/menu_images/1x1.gif diff --git a/webgoat-container/src/main/webapp/images/webBg.png b/webgoat-container/src/main/resources/static/images/webBg.png similarity index 100% rename from webgoat-container/src/main/webapp/images/webBg.png rename to webgoat-container/src/main/resources/static/images/webBg.png diff --git a/webgoat-container/src/main/webapp/js/DOMXSS_backup.js b/webgoat-container/src/main/resources/static/js/DOMXSS_backup.js similarity index 96% rename from webgoat-container/src/main/webapp/js/DOMXSS_backup.js rename to webgoat-container/src/main/resources/static/js/DOMXSS_backup.js index 9ddb31a10..2229cdbd3 100644 --- a/webgoat-container/src/main/webapp/js/DOMXSS_backup.js +++ b/webgoat-container/src/main/resources/static/js/DOMXSS_backup.js @@ -1,5 +1,5 @@ -function displayGreeting(name) { - if (name != ''){ - document.getElementById("greeting").innerHTML="Hello, " + name+ "!"; - } +function displayGreeting(name) { + if (name != ''){ + document.getElementById("greeting").innerHTML="Hello, " + name+ "!"; + } } \ No newline at end of file diff --git a/webgoat-container/src/main/webapp/js/application.js b/webgoat-container/src/main/resources/static/js/application.js similarity index 96% rename from webgoat-container/src/main/webapp/js/application.js rename to webgoat-container/src/main/resources/static/js/application.js index 0bf45e4aa..7a955728c 100644 --- a/webgoat-container/src/main/webapp/js/application.js +++ b/webgoat-container/src/main/resources/static/js/application.js @@ -1,226 +1,226 @@ -var app = function() { - - var init = function() { - - tooltips(); - toggleMenuLeft(); - toggleMenuRight(); - // menu is handled by angular - //menu(); - togglePanel(); - sideBarLeftInit(); - window.onresize = function(){ - sideBarLeftInit(); - } - closePanel(); - }; - - var tooltips = function() { - $('#toggle-left').tooltip(); - $('.right_nav_button').tooltip({'placement': 'bottom'}); - }; - - var togglePanel = function() { - $('.actions > .fa-chevron-down').click(function() { - $(this).parent().parent().next().slideToggle('fast'); - $(this).toggleClass('fa-chevron-down fa-chevron-up'); - }); - - }; - - var toggleMenuLeft = function() { - $('#toggle-left').bind('click', function(e) { - if (!$('.sidebarRight').hasClass('.sidebar-toggle-right')) { - $('.sidebarRight').removeClass('sidebar-toggle-right'); - $('.main-content-wrapper').removeClass('main-content-toggle-right'); - } - $('.sidebar').toggleClass('sidebar-toggle'); - $('.main-content-wrapper').toggleClass('main-content-toggle-left'); - e.stopPropagation(); - }); - }; - - var toggleMenuRight = function() { - $('#toggle-right').bind('click', function(e) { - - if (!$('.sidebar').hasClass('.sidebar-toggle')) { - $('.sidebar').addClass('sidebar-toggle'); - $('.main-content-wrapper').addClass('main-content-toggle-left'); - } - - $('.sidebarRight').toggleClass('sidebar-toggle-right animated bounceInRight'); - $('.main-content-wrapper').toggleClass('main-content-toggle-right'); - - if ( $(window).width() < 660 ) { - $('.sidebar').removeClass('sidebar-toggle'); - $('.main-content-wrapper').removeClass('main-content-toggle-left main-content-toggle-right'); - }; - - e.stopPropagation(); - }); - }; - - var closePanel = function() { - $('.actions > .fa-times').click(function() { - $(this).parent().parent().parent().fadeOut(); - }); - - } - - /* - var menu = function() { - $("#leftside-navigation .sub-menu a").click(function(e) { - $("#leftside-navigation ul ul").slideUp(); - if (!$(this).next().is(":visible")) { - $(this).next().slideDown(); - } - e.stopPropagation(); - }); - }; - */ - //End functions - - //Dashboard functions - var timer = function() { - $('.timer').countTo(); - }; - - - //Vector Maps - var map = function() { - $('#map').vectorMap({ - map: 'world_mill_en', - backgroundColor: 'transparent', - regionStyle: { - initial: { - fill: '#1ABC9C', - }, - hover: { - "fill-opacity": 0.8 - } - }, - markerStyle: { - initial: { - r: 10 - }, - hover: { - r: 12, - stroke: 'rgba(255,255,255,0.8)', - "stroke-width": 3 - } - }, - markers: [{ - latLng: [27.9881, 86.9253], - name: '36 Employees', - style: { - fill: '#E84C3D', - stroke: 'rgba(255,255,255,0.7)', - "stroke-width": 3 - } - }, { - latLng: [48.8582, 2.2945], - name: '58 Employees', - style: { - fill: '#E84C3D', - stroke: 'rgba(255,255,255,0.7)', - "stroke-width": 3 - } - }, { - latLng: [-40.6892, -74.0444], - name: '109 Employees', - style: { - fill: '#E84C3D', - stroke: 'rgba(255,255,255,0.7)', - "stroke-width": 3 - } - }, { - latLng: [34.05, -118.25], - name: '85 Employees ', - style: { - fill: '#E84C3D', - stroke: 'rgba(255,255,255,0.7)', - "stroke-width": 3 - } - }] - }); - - }; - - var weather = function() { - var icons = new Skycons({ - "color": "white" - }); - - icons.set("clear-day", Skycons.CLEAR_DAY); - icons.set("clear-night", Skycons.CLEAR_NIGHT); - icons.set("partly-cloudy-day", Skycons.PARTLY_CLOUDY_DAY); - icons.set("partly-cloudy-night", Skycons.PARTLY_CLOUDY_NIGHT); - icons.set("cloudy", Skycons.CLOUDY); - icons.set("rain", Skycons.RAIN); - icons.set("sleet", Skycons.SLEET); - icons.set("snow", Skycons.SNOW); - icons.set("wind", Skycons.WIND); - icons.set("fog", Skycons.FOG); - - icons.play(); - } - - //morris pie chart - var morrisPie = function() { - - Morris.Donut({ - element: 'donut-example', - data: [{ - label: "Chrome", - value: 73 - }, { - label: "Firefox", - value: 71 - }, { - label: "Safari", - value: 69 - }, { - label: "Internet Explorer", - value: 40 - }, { - label: "Opera", - value: 20 - }, { - label: "Android Browser", - value: 10 - } - - ], - colors: [ - '#1abc9c', - '#293949', - '#e84c3d', - '#3598db', - '#2dcc70', - '#f1c40f' - ] - }); - } - - //Sliders - var sliders = function() { - $('.slider-span').slider() - }; - - var sideBarLeftInit = function(){ - $("#leftside-navigation").css("height", (window.innerHeight-80)+"px"); - }; - - //return functions - return { - init: init, - timer: timer, - map: map, - sliders: sliders, - weather: weather, - morrisPie: morrisPie, - sideBarLeftInit:sideBarLeftInit - }; -}(); - - +var app = function() { + + var init = function() { + + tooltips(); + toggleMenuLeft(); + toggleMenuRight(); + // menu is handled by angular + //menu(); + togglePanel(); + sideBarLeftInit(); + window.onresize = function(){ + sideBarLeftInit(); + } + closePanel(); + }; + + var tooltips = function() { + $('#toggle-left').tooltip(); + $('.right_nav_button').tooltip({'placement': 'bottom'}); + }; + + var togglePanel = function() { + $('.actions > .fa-chevron-down').click(function() { + $(this).parent().parent().next().slideToggle('fast'); + $(this).toggleClass('fa-chevron-down fa-chevron-up'); + }); + + }; + + var toggleMenuLeft = function() { + $('#toggle-left').bind('click', function(e) { + if (!$('.sidebarRight').hasClass('.sidebar-toggle-right')) { + $('.sidebarRight').removeClass('sidebar-toggle-right'); + $('.main-content-wrapper').removeClass('main-content-toggle-right'); + } + $('.sidebar').toggleClass('sidebar-toggle'); + $('.main-content-wrapper').toggleClass('main-content-toggle-left'); + e.stopPropagation(); + }); + }; + + var toggleMenuRight = function() { + $('#toggle-right').bind('click', function(e) { + + if (!$('.sidebar').hasClass('.sidebar-toggle')) { + $('.sidebar').addClass('sidebar-toggle'); + $('.main-content-wrapper').addClass('main-content-toggle-left'); + } + + $('.sidebarRight').toggleClass('sidebar-toggle-right animated bounceInRight'); + $('.main-content-wrapper').toggleClass('main-content-toggle-right'); + + if ( $(window).width() < 660 ) { + $('.sidebar').removeClass('sidebar-toggle'); + $('.main-content-wrapper').removeClass('main-content-toggle-left main-content-toggle-right'); + }; + + e.stopPropagation(); + }); + }; + + var closePanel = function() { + $('.actions > .fa-times').click(function() { + $(this).parent().parent().parent().fadeOut(); + }); + + } + + /* + var menu = function() { + $("#leftside-navigation .sub-menu a").click(function(e) { + $("#leftside-navigation ul ul").slideUp(); + if (!$(this).next().is(":visible")) { + $(this).next().slideDown(); + } + e.stopPropagation(); + }); + }; + */ + //End functions + + //Dashboard functions + var timer = function() { + $('.timer').countTo(); + }; + + + //Vector Maps + var map = function() { + $('#map').vectorMap({ + map: 'world_mill_en', + backgroundColor: 'transparent', + regionStyle: { + initial: { + fill: '#1ABC9C', + }, + hover: { + "fill-opacity": 0.8 + } + }, + markerStyle: { + initial: { + r: 10 + }, + hover: { + r: 12, + stroke: 'rgba(255,255,255,0.8)', + "stroke-width": 3 + } + }, + markers: [{ + latLng: [27.9881, 86.9253], + name: '36 Employees', + style: { + fill: '#E84C3D', + stroke: 'rgba(255,255,255,0.7)', + "stroke-width": 3 + } + }, { + latLng: [48.8582, 2.2945], + name: '58 Employees', + style: { + fill: '#E84C3D', + stroke: 'rgba(255,255,255,0.7)', + "stroke-width": 3 + } + }, { + latLng: [-40.6892, -74.0444], + name: '109 Employees', + style: { + fill: '#E84C3D', + stroke: 'rgba(255,255,255,0.7)', + "stroke-width": 3 + } + }, { + latLng: [34.05, -118.25], + name: '85 Employees ', + style: { + fill: '#E84C3D', + stroke: 'rgba(255,255,255,0.7)', + "stroke-width": 3 + } + }] + }); + + }; + + var weather = function() { + var icons = new Skycons({ + "color": "white" + }); + + icons.set("clear-day", Skycons.CLEAR_DAY); + icons.set("clear-night", Skycons.CLEAR_NIGHT); + icons.set("partly-cloudy-day", Skycons.PARTLY_CLOUDY_DAY); + icons.set("partly-cloudy-night", Skycons.PARTLY_CLOUDY_NIGHT); + icons.set("cloudy", Skycons.CLOUDY); + icons.set("rain", Skycons.RAIN); + icons.set("sleet", Skycons.SLEET); + icons.set("snow", Skycons.SNOW); + icons.set("wind", Skycons.WIND); + icons.set("fog", Skycons.FOG); + + icons.play(); + } + + //morris pie chart + var morrisPie = function() { + + Morris.Donut({ + element: 'donut-example', + data: [{ + label: "Chrome", + value: 73 + }, { + label: "Firefox", + value: 71 + }, { + label: "Safari", + value: 69 + }, { + label: "Internet Explorer", + value: 40 + }, { + label: "Opera", + value: 20 + }, { + label: "Android Browser", + value: 10 + } + + ], + colors: [ + '#1abc9c', + '#293949', + '#e84c3d', + '#3598db', + '#2dcc70', + '#f1c40f' + ] + }); + } + + //Sliders + var sliders = function() { + $('.slider-span').slider() + }; + + var sideBarLeftInit = function(){ + $("#leftside-navigation").css("height", (window.innerHeight-80)+"px"); + }; + + //return functions + return { + init: init, + timer: timer, + map: map, + sliders: sliders, + weather: weather, + morrisPie: morrisPie, + sideBarLeftInit:sideBarLeftInit + }; +}(); + + diff --git a/webgoat-container/src/main/webapp/js/backbone/backbone-edge.js b/webgoat-container/src/main/resources/static/js/backbone/backbone-edge.js similarity index 100% rename from webgoat-container/src/main/webapp/js/backbone/backbone-edge.js rename to webgoat-container/src/main/resources/static/js/backbone/backbone-edge.js diff --git a/webgoat-container/src/main/webapp/js/backbone/backbone-min.js b/webgoat-container/src/main/resources/static/js/backbone/backbone-min.js similarity index 100% rename from webgoat-container/src/main/webapp/js/backbone/backbone-min.js rename to webgoat-container/src/main/resources/static/js/backbone/backbone-min.js diff --git a/webgoat-container/src/main/webapp/js/backbone/backbone.js b/webgoat-container/src/main/resources/static/js/backbone/backbone.js similarity index 100% rename from webgoat-container/src/main/webapp/js/backbone/backbone.js rename to webgoat-container/src/main/resources/static/js/backbone/backbone.js diff --git a/webgoat-container/src/main/webapp/js/backbone/underscore-min.js b/webgoat-container/src/main/resources/static/js/backbone/underscore-min.js similarity index 100% rename from webgoat-container/src/main/webapp/js/backbone/underscore-min.js rename to webgoat-container/src/main/resources/static/js/backbone/underscore-min.js diff --git a/webgoat-container/src/main/webapp/js/backbone/underscore.js b/webgoat-container/src/main/resources/static/js/backbone/underscore.js similarity index 100% rename from webgoat-container/src/main/webapp/js/backbone/underscore.js rename to webgoat-container/src/main/resources/static/js/backbone/underscore.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/controller/LessonController.js b/webgoat-container/src/main/resources/static/js/goatApp/controller/LessonController.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/controller/LessonController.js rename to webgoat-container/src/main/resources/static/js/goatApp/controller/LessonController.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/controller/MenuController.js b/webgoat-container/src/main/resources/static/js/goatApp/controller/MenuController.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/controller/MenuController.js rename to webgoat-container/src/main/resources/static/js/goatApp/controller/MenuController.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/goatApp.js b/webgoat-container/src/main/resources/static/js/goatApp/goatApp.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/goatApp.js rename to webgoat-container/src/main/resources/static/js/goatApp/goatApp.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/model/CookieCollection.js b/webgoat-container/src/main/resources/static/js/goatApp/model/CookieCollection.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/model/CookieCollection.js rename to webgoat-container/src/main/resources/static/js/goatApp/model/CookieCollection.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/model/CookieModel.js b/webgoat-container/src/main/resources/static/js/goatApp/model/CookieModel.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/model/CookieModel.js rename to webgoat-container/src/main/resources/static/js/goatApp/model/CookieModel.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/model/HTMLContentModel.js b/webgoat-container/src/main/resources/static/js/goatApp/model/HTMLContentModel.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/model/HTMLContentModel.js rename to webgoat-container/src/main/resources/static/js/goatApp/model/HTMLContentModel.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/model/HintCollection.js b/webgoat-container/src/main/resources/static/js/goatApp/model/HintCollection.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/model/HintCollection.js rename to webgoat-container/src/main/resources/static/js/goatApp/model/HintCollection.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/model/HintModel.js b/webgoat-container/src/main/resources/static/js/goatApp/model/HintModel.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/model/HintModel.js rename to webgoat-container/src/main/resources/static/js/goatApp/model/HintModel.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/model/LessonContentModel.js b/webgoat-container/src/main/resources/static/js/goatApp/model/LessonContentModel.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/model/LessonContentModel.js rename to webgoat-container/src/main/resources/static/js/goatApp/model/LessonContentModel.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/model/LessonInfoModel.js b/webgoat-container/src/main/resources/static/js/goatApp/model/LessonInfoModel.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/model/LessonInfoModel.js rename to webgoat-container/src/main/resources/static/js/goatApp/model/LessonInfoModel.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/model/LessonPlanModel.js b/webgoat-container/src/main/resources/static/js/goatApp/model/LessonPlanModel.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/model/LessonPlanModel.js rename to webgoat-container/src/main/resources/static/js/goatApp/model/LessonPlanModel.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/model/MenuCollection.js b/webgoat-container/src/main/resources/static/js/goatApp/model/MenuCollection.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/model/MenuCollection.js rename to webgoat-container/src/main/resources/static/js/goatApp/model/MenuCollection.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/model/MenuData.js b/webgoat-container/src/main/resources/static/js/goatApp/model/MenuData.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/model/MenuData.js rename to webgoat-container/src/main/resources/static/js/goatApp/model/MenuData.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/model/MenuModel.js b/webgoat-container/src/main/resources/static/js/goatApp/model/MenuModel.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/model/MenuModel.js rename to webgoat-container/src/main/resources/static/js/goatApp/model/MenuModel.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/model/ParamModel.js b/webgoat-container/src/main/resources/static/js/goatApp/model/ParamModel.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/model/ParamModel.js rename to webgoat-container/src/main/resources/static/js/goatApp/model/ParamModel.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/model/SolutionModel.js b/webgoat-container/src/main/resources/static/js/goatApp/model/SolutionModel.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/model/SolutionModel.js rename to webgoat-container/src/main/resources/static/js/goatApp/model/SolutionModel.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/model/SourceModel.js b/webgoat-container/src/main/resources/static/js/goatApp/model/SourceModel.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/model/SourceModel.js rename to webgoat-container/src/main/resources/static/js/goatApp/model/SourceModel.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/support/GoatUtils.js b/webgoat-container/src/main/resources/static/js/goatApp/support/GoatUtils.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/support/GoatUtils.js rename to webgoat-container/src/main/resources/static/js/goatApp/support/GoatUtils.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/support/goatConstants.js b/webgoat-container/src/main/resources/static/js/goatApp/support/goatConstants.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/support/goatConstants.js rename to webgoat-container/src/main/resources/static/js/goatApp/support/goatConstants.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/view/CookieView.js b/webgoat-container/src/main/resources/static/js/goatApp/view/CookieView.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/view/CookieView.js rename to webgoat-container/src/main/resources/static/js/goatApp/view/CookieView.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/view/GoatRouter.js b/webgoat-container/src/main/resources/static/js/goatApp/view/GoatRouter.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/view/GoatRouter.js rename to webgoat-container/src/main/resources/static/js/goatApp/view/GoatRouter.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/view/HelpControlsView.js b/webgoat-container/src/main/resources/static/js/goatApp/view/HelpControlsView.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/view/HelpControlsView.js rename to webgoat-container/src/main/resources/static/js/goatApp/view/HelpControlsView.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/view/HelpView.js b/webgoat-container/src/main/resources/static/js/goatApp/view/HelpView.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/view/HelpView.js rename to webgoat-container/src/main/resources/static/js/goatApp/view/HelpView.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/view/HintView.js b/webgoat-container/src/main/resources/static/js/goatApp/view/HintView.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/view/HintView.js rename to webgoat-container/src/main/resources/static/js/goatApp/view/HintView.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/view/LessonContentView.js b/webgoat-container/src/main/resources/static/js/goatApp/view/LessonContentView.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/view/LessonContentView.js rename to webgoat-container/src/main/resources/static/js/goatApp/view/LessonContentView.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/view/MenuButtonView.js b/webgoat-container/src/main/resources/static/js/goatApp/view/MenuButtonView.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/view/MenuButtonView.js rename to webgoat-container/src/main/resources/static/js/goatApp/view/MenuButtonView.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/view/MenuItemView.js b/webgoat-container/src/main/resources/static/js/goatApp/view/MenuItemView.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/view/MenuItemView.js rename to webgoat-container/src/main/resources/static/js/goatApp/view/MenuItemView.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/view/MenuStageView.js b/webgoat-container/src/main/resources/static/js/goatApp/view/MenuStageView.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/view/MenuStageView.js rename to webgoat-container/src/main/resources/static/js/goatApp/view/MenuStageView.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/view/MenuView.js b/webgoat-container/src/main/resources/static/js/goatApp/view/MenuView.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/view/MenuView.js rename to webgoat-container/src/main/resources/static/js/goatApp/view/MenuView.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/view/ParamView.js b/webgoat-container/src/main/resources/static/js/goatApp/view/ParamView.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/view/ParamView.js rename to webgoat-container/src/main/resources/static/js/goatApp/view/ParamView.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/view/PlanView.js b/webgoat-container/src/main/resources/static/js/goatApp/view/PlanView.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/view/PlanView.js rename to webgoat-container/src/main/resources/static/js/goatApp/view/PlanView.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/view/SolutionView.js b/webgoat-container/src/main/resources/static/js/goatApp/view/SolutionView.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/view/SolutionView.js rename to webgoat-container/src/main/resources/static/js/goatApp/view/SolutionView.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/view/SourceView.js b/webgoat-container/src/main/resources/static/js/goatApp/view/SourceView.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/view/SourceView.js rename to webgoat-container/src/main/resources/static/js/goatApp/view/SourceView.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/view/TitleView.js b/webgoat-container/src/main/resources/static/js/goatApp/view/TitleView.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/view/TitleView.js rename to webgoat-container/src/main/resources/static/js/goatApp/view/TitleView.js diff --git a/webgoat-container/src/main/webapp/js/goatApp/view/UserAndInfoView.js b/webgoat-container/src/main/resources/static/js/goatApp/view/UserAndInfoView.js similarity index 100% rename from webgoat-container/src/main/webapp/js/goatApp/view/UserAndInfoView.js rename to webgoat-container/src/main/resources/static/js/goatApp/view/UserAndInfoView.js diff --git a/webgoat-container/src/main/webapp/js/html5shiv.js b/webgoat-container/src/main/resources/static/js/html5shiv.js similarity index 99% rename from webgoat-container/src/main/webapp/js/html5shiv.js rename to webgoat-container/src/main/resources/static/js/html5shiv.js index e2e00155b..448cebd79 100644 --- a/webgoat-container/src/main/webapp/js/html5shiv.js +++ b/webgoat-container/src/main/resources/static/js/html5shiv.js @@ -1,8 +1,8 @@ -/* - HTML5 Shiv v3.7.0 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed -*/ -(function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag(); -a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/[\w\-]+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x"; -c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode|| -"undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:"3.7.0",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f); -if(g)return a.createDocumentFragment();for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;darticle,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}"; +c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode|| +"undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:"3.7.0",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f); +if(g)return a.createDocumentFragment();for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d'+ - '
'+ - '
'+ - '
'+ - '
'+ - '
'+ - '
'+ - '') - .insertBefore(this.element) - .append(this.element); - this.id = this.element.data('slider-id')||options.id; - if (this.id) { - this.picker[0].id = this.id; - } - - if (typeof Modernizr !== 'undefined' && Modernizr.touch) { - this.touchCapable = true; - } - - var tooltip = this.element.data('slider-tooltip')||options.tooltip; - - this.tooltip = this.picker.find('.tooltip'); - this.tooltipInner = this.tooltip.find('div.tooltip-inner'); - - this.orientation = this.element.data('slider-orientation')||options.orientation; - switch(this.orientation) { - case 'vertical': - this.picker.addClass('slider-vertical'); - this.stylePos = 'top'; - this.mousePos = 'pageY'; - this.sizePos = 'offsetHeight'; - this.tooltip.addClass('right')[0].style.left = '100%'; - break; - default: - this.picker - .addClass('slider-horizontal') - .css('width', this.element.outerWidth()); - this.orientation = 'horizontal'; - this.stylePos = 'left'; - this.mousePos = 'pageX'; - this.sizePos = 'offsetWidth'; - this.tooltip.addClass('top')[0].style.top = -this.tooltip.outerHeight() - 14 + 'px'; - break; - } - - this.min = this.element.data('slider-min')||options.min; - this.max = this.element.data('slider-max')||options.max; - this.step = this.element.data('slider-step')||options.step; - this.value = this.element.data('slider-value')||options.value; - if (this.value[1]) { - this.range = true; - } - - this.selection = this.element.data('slider-selection')||options.selection; - this.selectionEl = this.picker.find('.slider-selection'); - if (this.selection === 'none') { - this.selectionEl.addClass('hide'); - } - this.selectionElStyle = this.selectionEl[0].style; - - - this.handle1 = this.picker.find('.slider-handle:first'); - this.handle1Stype = this.handle1[0].style; - this.handle2 = this.picker.find('.slider-handle:last'); - this.handle2Stype = this.handle2[0].style; - - var handle = this.element.data('slider-handle')||options.handle; - switch(handle) { - case 'round': - this.handle1.addClass('round'); - this.handle2.addClass('round'); - break - case 'triangle': - this.handle1.addClass('triangle'); - this.handle2.addClass('triangle'); - break - } - - if (this.range) { - this.value[0] = Math.max(this.min, Math.min(this.max, this.value[0])); - this.value[1] = Math.max(this.min, Math.min(this.max, this.value[1])); - } else { - this.value = [ Math.max(this.min, Math.min(this.max, this.value))]; - this.handle2.addClass('hide'); - if (this.selection == 'after') { - this.value[1] = this.max; - } else { - this.value[1] = this.min; - } - } - this.diff = this.max - this.min; - this.percentage = [ - (this.value[0]-this.min)*100/this.diff, - (this.value[1]-this.min)*100/this.diff, - this.step*100/this.diff - ]; - - this.offset = this.picker.offset(); - this.size = this.picker[0][this.sizePos]; - - this.formater = options.formater; - - this.layout(); - - if (this.touchCapable) { - // Touch: Bind touch events: - this.picker.on({ - touchstart: $.proxy(this.mousedown, this) - }); - } else { - this.picker.on({ - mousedown: $.proxy(this.mousedown, this) - }); - } - - if (tooltip === 'show') { - this.picker.on({ - mouseenter: $.proxy(this.showTooltip, this), - mouseleave: $.proxy(this.hideTooltip, this) - }); - } else { - this.tooltip.addClass('hide'); - } - }; - - Slider.prototype = { - constructor: Slider, - - over: false, - inDrag: false, - - showTooltip: function(){ - this.tooltip.addClass('in'); - //var left = Math.round(this.percent*this.width); - //this.tooltip.css('left', left - this.tooltip.outerWidth()/2); - this.over = true; - }, - - hideTooltip: function(){ - if (this.inDrag === false) { - this.tooltip.removeClass('in'); - } - this.over = false; - }, - - layout: function(){ - this.handle1Stype[this.stylePos] = this.percentage[0]+'%'; - this.handle2Stype[this.stylePos] = this.percentage[1]+'%'; - if (this.orientation == 'vertical') { - this.selectionElStyle.top = Math.min(this.percentage[0], this.percentage[1]) +'%'; - this.selectionElStyle.height = Math.abs(this.percentage[0] - this.percentage[1]) +'%'; - } else { - this.selectionElStyle.left = Math.min(this.percentage[0], this.percentage[1]) +'%'; - this.selectionElStyle.width = Math.abs(this.percentage[0] - this.percentage[1]) +'%'; - } - if (this.range) { - this.tooltipInner.text( - this.formater(this.value[0]) + - ' : ' + - this.formater(this.value[1]) - ); - this.tooltip[0].style[this.stylePos] = this.size * (this.percentage[0] + (this.percentage[1] - this.percentage[0])/2)/100 - (this.orientation === 'vertical' ? this.tooltip.outerHeight()/2 : this.tooltip.outerWidth()/2) +'px'; - } else { - this.tooltipInner.text( - this.formater(this.value[0]) - ); - this.tooltip[0].style[this.stylePos] = this.size * this.percentage[0]/100 - (this.orientation === 'vertical' ? this.tooltip.outerHeight()/2 : this.tooltip.outerWidth()/2) +'px'; - } - }, - - mousedown: function(ev) { - - // Touch: Get the original event: - if (this.touchCapable && ev.type === 'touchstart') { - ev = ev.originalEvent; - } - - this.offset = this.picker.offset(); - this.size = this.picker[0][this.sizePos]; - - var percentage = this.getPercentage(ev); - - if (this.range) { - var diff1 = Math.abs(this.percentage[0] - percentage); - var diff2 = Math.abs(this.percentage[1] - percentage); - this.dragged = (diff1 < diff2) ? 0 : 1; - } else { - this.dragged = 0; - } - - this.percentage[this.dragged] = percentage; - this.layout(); - - if (this.touchCapable) { - // Touch: Bind touch events: - $(document).on({ - touchmove: $.proxy(this.mousemove, this), - touchend: $.proxy(this.mouseup, this) - }); - } else { - $(document).on({ - mousemove: $.proxy(this.mousemove, this), - mouseup: $.proxy(this.mouseup, this) - }); - } - - this.inDrag = true; - var val = this.calculateValue(); - this.element.trigger({ - type: 'slideStart', - value: val - }).trigger({ - type: 'slide', - value: val - }); - return false; - }, - - mousemove: function(ev) { - - // Touch: Get the original event: - if (this.touchCapable && ev.type === 'touchmove') { - ev = ev.originalEvent; - } - - var percentage = this.getPercentage(ev); - if (this.range) { - if (this.dragged === 0 && this.percentage[1] < percentage) { - this.percentage[0] = this.percentage[1]; - this.dragged = 1; - } else if (this.dragged === 1 && this.percentage[0] > percentage) { - this.percentage[1] = this.percentage[0]; - this.dragged = 0; - } - } - this.percentage[this.dragged] = percentage; - this.layout(); - var val = this.calculateValue(); - this.element - .trigger({ - type: 'slide', - value: val - }) - .data('value', val) - .prop('value', val); - return false; - }, - - mouseup: function(ev) { - if (this.touchCapable) { - // Touch: Bind touch events: - $(document).off({ - touchmove: this.mousemove, - touchend: this.mouseup - }); - } else { - $(document).off({ - mousemove: this.mousemove, - mouseup: this.mouseup - }); - } - - this.inDrag = false; - if (this.over == false) { - this.hideTooltip(); - } - this.element; - var val = this.calculateValue(); - this.element - .trigger({ - type: 'slideStop', - value: val - }) - .data('value', val) - .prop('value', val); - return false; - }, - - calculateValue: function() { - var val; - if (this.range) { - val = [ - (this.min + Math.round((this.diff * this.percentage[0]/100)/this.step)*this.step), - (this.min + Math.round((this.diff * this.percentage[1]/100)/this.step)*this.step) - ]; - this.value = val; - } else { - val = (this.min + Math.round((this.diff * this.percentage[0]/100)/this.step)*this.step); - this.value = [val, this.value[1]]; - } - return val; - }, - - getPercentage: function(ev) { - if (this.touchCapable) { - ev = ev.touches[0]; - } - var percentage = (ev[this.mousePos] - this.offset[this.stylePos])*100/this.size; - percentage = Math.round(percentage/this.percentage[2])*this.percentage[2]; - return Math.max(0, Math.min(100, percentage)); - }, - - getValue: function() { - if (this.range) { - return this.value; - } - return this.value[0]; - }, - - setValue: function(val) { - this.value = val; - - if (this.range) { - this.value[0] = Math.max(this.min, Math.min(this.max, this.value[0])); - this.value[1] = Math.max(this.min, Math.min(this.max, this.value[1])); - } else { - this.value = [ Math.max(this.min, Math.min(this.max, this.value))]; - this.handle2.addClass('hide'); - if (this.selection == 'after') { - this.value[1] = this.max; - } else { - this.value[1] = this.min; - } - } - this.diff = this.max - this.min; - this.percentage = [ - (this.value[0]-this.min)*100/this.diff, - (this.value[1]-this.min)*100/this.diff, - this.step*100/this.diff - ]; - this.layout(); - } - }; - - $.fn.slider = function ( option, val ) { - return this.each(function () { - var $this = $(this), - data = $this.data('slider'), - options = typeof option === 'object' && option; - if (!data) { - $this.data('slider', (data = new Slider(this, $.extend({}, $.fn.slider.defaults,options)))); - } - if (typeof option == 'string') { - data[option](val); - } - }) - }; - - $.fn.slider.defaults = { - min: 0, - max: 10, - step: 1, - orientation: 'horizontal', - value: 5, - selection: 'before', - tooltip: 'show', - handle: 'round', - formater: function(value) { - return value; - } - }; - - $.fn.slider.Constructor = Slider; - +/* ========================================================= + * bootstrap-slider.js v2.0.0 + * http://www.eyecon.ro/bootstrap-slider + * ========================================================= + * Copyright 2012 Stefan Petre + * + * 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( $ ) { + + var Slider = function(element, options) { + this.element = $(element); + this.picker = $('
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
') + .insertBefore(this.element) + .append(this.element); + this.id = this.element.data('slider-id')||options.id; + if (this.id) { + this.picker[0].id = this.id; + } + + if (typeof Modernizr !== 'undefined' && Modernizr.touch) { + this.touchCapable = true; + } + + var tooltip = this.element.data('slider-tooltip')||options.tooltip; + + this.tooltip = this.picker.find('.tooltip'); + this.tooltipInner = this.tooltip.find('div.tooltip-inner'); + + this.orientation = this.element.data('slider-orientation')||options.orientation; + switch(this.orientation) { + case 'vertical': + this.picker.addClass('slider-vertical'); + this.stylePos = 'top'; + this.mousePos = 'pageY'; + this.sizePos = 'offsetHeight'; + this.tooltip.addClass('right')[0].style.left = '100%'; + break; + default: + this.picker + .addClass('slider-horizontal') + .css('width', this.element.outerWidth()); + this.orientation = 'horizontal'; + this.stylePos = 'left'; + this.mousePos = 'pageX'; + this.sizePos = 'offsetWidth'; + this.tooltip.addClass('top')[0].style.top = -this.tooltip.outerHeight() - 14 + 'px'; + break; + } + + this.min = this.element.data('slider-min')||options.min; + this.max = this.element.data('slider-max')||options.max; + this.step = this.element.data('slider-step')||options.step; + this.value = this.element.data('slider-value')||options.value; + if (this.value[1]) { + this.range = true; + } + + this.selection = this.element.data('slider-selection')||options.selection; + this.selectionEl = this.picker.find('.slider-selection'); + if (this.selection === 'none') { + this.selectionEl.addClass('hide'); + } + this.selectionElStyle = this.selectionEl[0].style; + + + this.handle1 = this.picker.find('.slider-handle:first'); + this.handle1Stype = this.handle1[0].style; + this.handle2 = this.picker.find('.slider-handle:last'); + this.handle2Stype = this.handle2[0].style; + + var handle = this.element.data('slider-handle')||options.handle; + switch(handle) { + case 'round': + this.handle1.addClass('round'); + this.handle2.addClass('round'); + break + case 'triangle': + this.handle1.addClass('triangle'); + this.handle2.addClass('triangle'); + break + } + + if (this.range) { + this.value[0] = Math.max(this.min, Math.min(this.max, this.value[0])); + this.value[1] = Math.max(this.min, Math.min(this.max, this.value[1])); + } else { + this.value = [ Math.max(this.min, Math.min(this.max, this.value))]; + this.handle2.addClass('hide'); + if (this.selection == 'after') { + this.value[1] = this.max; + } else { + this.value[1] = this.min; + } + } + this.diff = this.max - this.min; + this.percentage = [ + (this.value[0]-this.min)*100/this.diff, + (this.value[1]-this.min)*100/this.diff, + this.step*100/this.diff + ]; + + this.offset = this.picker.offset(); + this.size = this.picker[0][this.sizePos]; + + this.formater = options.formater; + + this.layout(); + + if (this.touchCapable) { + // Touch: Bind touch events: + this.picker.on({ + touchstart: $.proxy(this.mousedown, this) + }); + } else { + this.picker.on({ + mousedown: $.proxy(this.mousedown, this) + }); + } + + if (tooltip === 'show') { + this.picker.on({ + mouseenter: $.proxy(this.showTooltip, this), + mouseleave: $.proxy(this.hideTooltip, this) + }); + } else { + this.tooltip.addClass('hide'); + } + }; + + Slider.prototype = { + constructor: Slider, + + over: false, + inDrag: false, + + showTooltip: function(){ + this.tooltip.addClass('in'); + //var left = Math.round(this.percent*this.width); + //this.tooltip.css('left', left - this.tooltip.outerWidth()/2); + this.over = true; + }, + + hideTooltip: function(){ + if (this.inDrag === false) { + this.tooltip.removeClass('in'); + } + this.over = false; + }, + + layout: function(){ + this.handle1Stype[this.stylePos] = this.percentage[0]+'%'; + this.handle2Stype[this.stylePos] = this.percentage[1]+'%'; + if (this.orientation == 'vertical') { + this.selectionElStyle.top = Math.min(this.percentage[0], this.percentage[1]) +'%'; + this.selectionElStyle.height = Math.abs(this.percentage[0] - this.percentage[1]) +'%'; + } else { + this.selectionElStyle.left = Math.min(this.percentage[0], this.percentage[1]) +'%'; + this.selectionElStyle.width = Math.abs(this.percentage[0] - this.percentage[1]) +'%'; + } + if (this.range) { + this.tooltipInner.text( + this.formater(this.value[0]) + + ' : ' + + this.formater(this.value[1]) + ); + this.tooltip[0].style[this.stylePos] = this.size * (this.percentage[0] + (this.percentage[1] - this.percentage[0])/2)/100 - (this.orientation === 'vertical' ? this.tooltip.outerHeight()/2 : this.tooltip.outerWidth()/2) +'px'; + } else { + this.tooltipInner.text( + this.formater(this.value[0]) + ); + this.tooltip[0].style[this.stylePos] = this.size * this.percentage[0]/100 - (this.orientation === 'vertical' ? this.tooltip.outerHeight()/2 : this.tooltip.outerWidth()/2) +'px'; + } + }, + + mousedown: function(ev) { + + // Touch: Get the original event: + if (this.touchCapable && ev.type === 'touchstart') { + ev = ev.originalEvent; + } + + this.offset = this.picker.offset(); + this.size = this.picker[0][this.sizePos]; + + var percentage = this.getPercentage(ev); + + if (this.range) { + var diff1 = Math.abs(this.percentage[0] - percentage); + var diff2 = Math.abs(this.percentage[1] - percentage); + this.dragged = (diff1 < diff2) ? 0 : 1; + } else { + this.dragged = 0; + } + + this.percentage[this.dragged] = percentage; + this.layout(); + + if (this.touchCapable) { + // Touch: Bind touch events: + $(document).on({ + touchmove: $.proxy(this.mousemove, this), + touchend: $.proxy(this.mouseup, this) + }); + } else { + $(document).on({ + mousemove: $.proxy(this.mousemove, this), + mouseup: $.proxy(this.mouseup, this) + }); + } + + this.inDrag = true; + var val = this.calculateValue(); + this.element.trigger({ + type: 'slideStart', + value: val + }).trigger({ + type: 'slide', + value: val + }); + return false; + }, + + mousemove: function(ev) { + + // Touch: Get the original event: + if (this.touchCapable && ev.type === 'touchmove') { + ev = ev.originalEvent; + } + + var percentage = this.getPercentage(ev); + if (this.range) { + if (this.dragged === 0 && this.percentage[1] < percentage) { + this.percentage[0] = this.percentage[1]; + this.dragged = 1; + } else if (this.dragged === 1 && this.percentage[0] > percentage) { + this.percentage[1] = this.percentage[0]; + this.dragged = 0; + } + } + this.percentage[this.dragged] = percentage; + this.layout(); + var val = this.calculateValue(); + this.element + .trigger({ + type: 'slide', + value: val + }) + .data('value', val) + .prop('value', val); + return false; + }, + + mouseup: function(ev) { + if (this.touchCapable) { + // Touch: Bind touch events: + $(document).off({ + touchmove: this.mousemove, + touchend: this.mouseup + }); + } else { + $(document).off({ + mousemove: this.mousemove, + mouseup: this.mouseup + }); + } + + this.inDrag = false; + if (this.over == false) { + this.hideTooltip(); + } + this.element; + var val = this.calculateValue(); + this.element + .trigger({ + type: 'slideStop', + value: val + }) + .data('value', val) + .prop('value', val); + return false; + }, + + calculateValue: function() { + var val; + if (this.range) { + val = [ + (this.min + Math.round((this.diff * this.percentage[0]/100)/this.step)*this.step), + (this.min + Math.round((this.diff * this.percentage[1]/100)/this.step)*this.step) + ]; + this.value = val; + } else { + val = (this.min + Math.round((this.diff * this.percentage[0]/100)/this.step)*this.step); + this.value = [val, this.value[1]]; + } + return val; + }, + + getPercentage: function(ev) { + if (this.touchCapable) { + ev = ev.touches[0]; + } + var percentage = (ev[this.mousePos] - this.offset[this.stylePos])*100/this.size; + percentage = Math.round(percentage/this.percentage[2])*this.percentage[2]; + return Math.max(0, Math.min(100, percentage)); + }, + + getValue: function() { + if (this.range) { + return this.value; + } + return this.value[0]; + }, + + setValue: function(val) { + this.value = val; + + if (this.range) { + this.value[0] = Math.max(this.min, Math.min(this.max, this.value[0])); + this.value[1] = Math.max(this.min, Math.min(this.max, this.value[1])); + } else { + this.value = [ Math.max(this.min, Math.min(this.max, this.value))]; + this.handle2.addClass('hide'); + if (this.selection == 'after') { + this.value[1] = this.max; + } else { + this.value[1] = this.min; + } + } + this.diff = this.max - this.min; + this.percentage = [ + (this.value[0]-this.min)*100/this.diff, + (this.value[1]-this.min)*100/this.diff, + this.step*100/this.diff + ]; + this.layout(); + } + }; + + $.fn.slider = function ( option, val ) { + return this.each(function () { + var $this = $(this), + data = $this.data('slider'), + options = typeof option === 'object' && option; + if (!data) { + $this.data('slider', (data = new Slider(this, $.extend({}, $.fn.slider.defaults,options)))); + } + if (typeof option == 'string') { + data[option](val); + } + }) + }; + + $.fn.slider.defaults = { + min: 0, + max: 10, + step: 1, + orientation: 'horizontal', + value: 5, + selection: 'before', + tooltip: 'show', + handle: 'round', + formater: function(value) { + return value; + } + }; + + $.fn.slider.Constructor = Slider; + }( window.jQuery ); \ No newline at end of file diff --git a/webgoat-container/src/main/webapp/plugins/bootstrap-wysihtml5/css/bootstrap-wysihtml5.css b/webgoat-container/src/main/resources/static/plugins/bootstrap-wysihtml5/css/bootstrap-wysihtml5.css similarity index 100% rename from webgoat-container/src/main/webapp/plugins/bootstrap-wysihtml5/css/bootstrap-wysihtml5.css rename to webgoat-container/src/main/resources/static/plugins/bootstrap-wysihtml5/css/bootstrap-wysihtml5.css diff --git a/webgoat-container/src/main/webapp/plugins/bootstrap-wysihtml5/css/bootstrap3-wysiwyg5-color.css b/webgoat-container/src/main/resources/static/plugins/bootstrap-wysihtml5/css/bootstrap3-wysiwyg5-color.css similarity index 100% rename from webgoat-container/src/main/webapp/plugins/bootstrap-wysihtml5/css/bootstrap3-wysiwyg5-color.css rename to webgoat-container/src/main/resources/static/plugins/bootstrap-wysihtml5/css/bootstrap3-wysiwyg5-color.css diff --git a/webgoat-container/src/main/webapp/plugins/bootstrap-wysihtml5/js/bootstrap3-wysihtml5.js b/webgoat-container/src/main/resources/static/plugins/bootstrap-wysihtml5/js/bootstrap3-wysihtml5.js similarity index 100% rename from webgoat-container/src/main/webapp/plugins/bootstrap-wysihtml5/js/bootstrap3-wysihtml5.js rename to webgoat-container/src/main/resources/static/plugins/bootstrap-wysihtml5/js/bootstrap3-wysihtml5.js diff --git a/webgoat-container/src/main/webapp/plugins/bootstrap-wysihtml5/js/wysihtml5-0.3.0.js b/webgoat-container/src/main/resources/static/plugins/bootstrap-wysihtml5/js/wysihtml5-0.3.0.js similarity index 97% rename from webgoat-container/src/main/webapp/plugins/bootstrap-wysihtml5/js/wysihtml5-0.3.0.js rename to webgoat-container/src/main/resources/static/plugins/bootstrap-wysihtml5/js/wysihtml5-0.3.0.js index 7afa8f781..6bce5112a 100644 --- a/webgoat-container/src/main/webapp/plugins/bootstrap-wysihtml5/js/wysihtml5-0.3.0.js +++ b/webgoat-container/src/main/resources/static/plugins/bootstrap-wysihtml5/js/wysihtml5-0.3.0.js @@ -1,9523 +1,9523 @@ -/** - * @license wysihtml5 v0.3.0 - * https://github.com/xing/wysihtml5 - * - * Author: Christopher Blum (https://github.com/tiff) - * - * Copyright (C) 2012 XING AG - * Licensed under the MIT license (MIT) - * - */ -var wysihtml5 = { - version: "0.3.0", - - // namespaces - commands: {}, - dom: {}, - quirks: {}, - toolbar: {}, - lang: {}, - selection: {}, - views: {}, - - INVISIBLE_SPACE: "\uFEFF", - - EMPTY_FUNCTION: function() {}, - - ELEMENT_NODE: 1, - TEXT_NODE: 3, - - BACKSPACE_KEY: 8, - ENTER_KEY: 13, - ESCAPE_KEY: 27, - SPACE_KEY: 32, - DELETE_KEY: 46 -};/** - * @license Rangy, a cross-browser JavaScript range and selection library - * http://code.google.com/p/rangy/ - * - * Copyright 2011, Tim Down - * Licensed under the MIT license. - * Version: 1.2.2 - * Build date: 13 November 2011 - */ -window['rangy'] = (function() { - - - var OBJECT = "object", FUNCTION = "function", UNDEFINED = "undefined"; - - var domRangeProperties = ["startContainer", "startOffset", "endContainer", "endOffset", "collapsed", - "commonAncestorContainer", "START_TO_START", "START_TO_END", "END_TO_START", "END_TO_END"]; - - var domRangeMethods = ["setStart", "setStartBefore", "setStartAfter", "setEnd", "setEndBefore", - "setEndAfter", "collapse", "selectNode", "selectNodeContents", "compareBoundaryPoints", "deleteContents", - "extractContents", "cloneContents", "insertNode", "surroundContents", "cloneRange", "toString", "detach"]; - - var textRangeProperties = ["boundingHeight", "boundingLeft", "boundingTop", "boundingWidth", "htmlText", "text"]; - - // Subset of TextRange's full set of methods that we're interested in - var textRangeMethods = ["collapse", "compareEndPoints", "duplicate", "getBookmark", "moveToBookmark", - "moveToElementText", "parentElement", "pasteHTML", "select", "setEndPoint", "getBoundingClientRect"]; - - /*----------------------------------------------------------------------------------------------------------------*/ - - // Trio of functions taken from Peter Michaux's article: - // http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting - function isHostMethod(o, p) { - var t = typeof o[p]; - return t == FUNCTION || (!!(t == OBJECT && o[p])) || t == "unknown"; - } - - function isHostObject(o, p) { - return !!(typeof o[p] == OBJECT && o[p]); - } - - function isHostProperty(o, p) { - return typeof o[p] != UNDEFINED; - } - - // Creates a convenience function to save verbose repeated calls to tests functions - function createMultiplePropertyTest(testFunc) { - return function(o, props) { - var i = props.length; - while (i--) { - if (!testFunc(o, props[i])) { - return false; - } - } - return true; - }; - } - - // Next trio of functions are a convenience to save verbose repeated calls to previous two functions - var areHostMethods = createMultiplePropertyTest(isHostMethod); - var areHostObjects = createMultiplePropertyTest(isHostObject); - var areHostProperties = createMultiplePropertyTest(isHostProperty); - - function isTextRange(range) { - return range && areHostMethods(range, textRangeMethods) && areHostProperties(range, textRangeProperties); - } - - var api = { - version: "1.2.2", - initialized: false, - supported: true, - - util: { - isHostMethod: isHostMethod, - isHostObject: isHostObject, - isHostProperty: isHostProperty, - areHostMethods: areHostMethods, - areHostObjects: areHostObjects, - areHostProperties: areHostProperties, - isTextRange: isTextRange - }, - - features: {}, - - modules: {}, - config: { - alertOnWarn: false, - preferTextRange: false - } - }; - - function fail(reason) { - window.alert("Rangy not supported in your browser. Reason: " + reason); - api.initialized = true; - api.supported = false; - } - - api.fail = fail; - - function warn(msg) { - var warningMessage = "Rangy warning: " + msg; - if (api.config.alertOnWarn) { - window.alert(warningMessage); - } else if (typeof window.console != UNDEFINED && typeof window.console.log != UNDEFINED) { - window.console.log(warningMessage); - } - } - - api.warn = warn; - - if ({}.hasOwnProperty) { - api.util.extend = function(o, props) { - for (var i in props) { - if (props.hasOwnProperty(i)) { - o[i] = props[i]; - } - } - }; - } else { - fail("hasOwnProperty not supported"); - } - - var initListeners = []; - var moduleInitializers = []; - - // Initialization - function init() { - if (api.initialized) { - return; - } - var testRange; - var implementsDomRange = false, implementsTextRange = false; - - // First, perform basic feature tests - - if (isHostMethod(document, "createRange")) { - testRange = document.createRange(); - if (areHostMethods(testRange, domRangeMethods) && areHostProperties(testRange, domRangeProperties)) { - implementsDomRange = true; - } - testRange.detach(); - } - - var body = isHostObject(document, "body") ? document.body : document.getElementsByTagName("body")[0]; - - if (body && isHostMethod(body, "createTextRange")) { - testRange = body.createTextRange(); - if (isTextRange(testRange)) { - implementsTextRange = true; - } - } - - if (!implementsDomRange && !implementsTextRange) { - fail("Neither Range nor TextRange are implemented"); - } - - api.initialized = true; - api.features = { - implementsDomRange: implementsDomRange, - implementsTextRange: implementsTextRange - }; - - // Initialize modules and call init listeners - var allListeners = moduleInitializers.concat(initListeners); - for (var i = 0, len = allListeners.length; i < len; ++i) { - try { - allListeners[i](api); - } catch (ex) { - if (isHostObject(window, "console") && isHostMethod(window.console, "log")) { - window.console.log("Init listener threw an exception. Continuing.", ex); - } - - } - } - } - - // Allow external scripts to initialize this library in case it's loaded after the document has loaded - api.init = init; - - // Execute listener immediately if already initialized - api.addInitListener = function(listener) { - if (api.initialized) { - listener(api); - } else { - initListeners.push(listener); - } - }; - - var createMissingNativeApiListeners = []; - - api.addCreateMissingNativeApiListener = function(listener) { - createMissingNativeApiListeners.push(listener); - }; - - function createMissingNativeApi(win) { - win = win || window; - init(); - - // Notify listeners - for (var i = 0, len = createMissingNativeApiListeners.length; i < len; ++i) { - createMissingNativeApiListeners[i](win); - } - } - - api.createMissingNativeApi = createMissingNativeApi; - - /** - * @constructor - */ - function Module(name) { - this.name = name; - this.initialized = false; - this.supported = false; - } - - Module.prototype.fail = function(reason) { - this.initialized = true; - this.supported = false; - - throw new Error("Module '" + this.name + "' failed to load: " + reason); - }; - - Module.prototype.warn = function(msg) { - api.warn("Module " + this.name + ": " + msg); - }; - - Module.prototype.createError = function(msg) { - return new Error("Error in Rangy " + this.name + " module: " + msg); - }; - - api.createModule = function(name, initFunc) { - var module = new Module(name); - api.modules[name] = module; - - moduleInitializers.push(function(api) { - initFunc(api, module); - module.initialized = true; - module.supported = true; - }); - }; - - api.requireModules = function(modules) { - for (var i = 0, len = modules.length, module, moduleName; i < len; ++i) { - moduleName = modules[i]; - module = api.modules[moduleName]; - if (!module || !(module instanceof Module)) { - throw new Error("Module '" + moduleName + "' not found"); - } - if (!module.supported) { - throw new Error("Module '" + moduleName + "' not supported"); - } - } - }; - - /*----------------------------------------------------------------------------------------------------------------*/ - - // Wait for document to load before running tests - - var docReady = false; - - var loadHandler = function(e) { - - if (!docReady) { - docReady = true; - if (!api.initialized) { - init(); - } - } - }; - - // Test whether we have window and document objects that we will need - if (typeof window == UNDEFINED) { - fail("No window found"); - return; - } - if (typeof document == UNDEFINED) { - fail("No document found"); - return; - } - - if (isHostMethod(document, "addEventListener")) { - document.addEventListener("DOMContentLoaded", loadHandler, false); - } - - // Add a fallback in case the DOMContentLoaded event isn't supported - if (isHostMethod(window, "addEventListener")) { - window.addEventListener("load", loadHandler, false); - } else if (isHostMethod(window, "attachEvent")) { - window.attachEvent("onload", loadHandler); - } else { - fail("Window does not have required addEventListener or attachEvent method"); - } - - return api; -})(); -rangy.createModule("DomUtil", function(api, module) { - - var UNDEF = "undefined"; - var util = api.util; - - // Perform feature tests - if (!util.areHostMethods(document, ["createDocumentFragment", "createElement", "createTextNode"])) { - module.fail("document missing a Node creation method"); - } - - if (!util.isHostMethod(document, "getElementsByTagName")) { - module.fail("document missing getElementsByTagName method"); - } - - var el = document.createElement("div"); - if (!util.areHostMethods(el, ["insertBefore", "appendChild", "cloneNode"] || - !util.areHostObjects(el, ["previousSibling", "nextSibling", "childNodes", "parentNode"]))) { - module.fail("Incomplete Element implementation"); - } - - // innerHTML is required for Range's createContextualFragment method - if (!util.isHostProperty(el, "innerHTML")) { - module.fail("Element is missing innerHTML property"); - } - - var textNode = document.createTextNode("test"); - if (!util.areHostMethods(textNode, ["splitText", "deleteData", "insertData", "appendData", "cloneNode"] || - !util.areHostObjects(el, ["previousSibling", "nextSibling", "childNodes", "parentNode"]) || - !util.areHostProperties(textNode, ["data"]))) { - module.fail("Incomplete Text Node implementation"); - } - - /*----------------------------------------------------------------------------------------------------------------*/ - - // Removed use of indexOf because of a bizarre bug in Opera that is thrown in one of the Acid3 tests. I haven't been - // able to replicate it outside of the test. The bug is that indexOf returns -1 when called on an Array that - // contains just the document as a single element and the value searched for is the document. - var arrayContains = /*Array.prototype.indexOf ? - function(arr, val) { - return arr.indexOf(val) > -1; - }:*/ - - function(arr, val) { - var i = arr.length; - while (i--) { - if (arr[i] === val) { - return true; - } - } - return false; - }; - - // Opera 11 puts HTML elements in the null namespace, it seems, and IE 7 has undefined namespaceURI - function isHtmlNamespace(node) { - var ns; - return typeof node.namespaceURI == UNDEF || ((ns = node.namespaceURI) === null || ns == "http://www.w3.org/1999/xhtml"); - } - - function parentElement(node) { - var parent = node.parentNode; - return (parent.nodeType == 1) ? parent : null; - } - - function getNodeIndex(node) { - var i = 0; - while( (node = node.previousSibling) ) { - i++; - } - return i; - } - - function getNodeLength(node) { - var childNodes; - return isCharacterDataNode(node) ? node.length : ((childNodes = node.childNodes) ? childNodes.length : 0); - } - - function getCommonAncestor(node1, node2) { - var ancestors = [], n; - for (n = node1; n; n = n.parentNode) { - ancestors.push(n); - } - - for (n = node2; n; n = n.parentNode) { - if (arrayContains(ancestors, n)) { - return n; - } - } - - return null; - } - - function isAncestorOf(ancestor, descendant, selfIsAncestor) { - var n = selfIsAncestor ? descendant : descendant.parentNode; - while (n) { - if (n === ancestor) { - return true; - } else { - n = n.parentNode; - } - } - return false; - } - - function getClosestAncestorIn(node, ancestor, selfIsAncestor) { - var p, n = selfIsAncestor ? node : node.parentNode; - while (n) { - p = n.parentNode; - if (p === ancestor) { - return n; - } - n = p; - } - return null; - } - - function isCharacterDataNode(node) { - var t = node.nodeType; - return t == 3 || t == 4 || t == 8 ; // Text, CDataSection or Comment - } - - function insertAfter(node, precedingNode) { - var nextNode = precedingNode.nextSibling, parent = precedingNode.parentNode; - if (nextNode) { - parent.insertBefore(node, nextNode); - } else { - parent.appendChild(node); - } - return node; - } - - // Note that we cannot use splitText() because it is bugridden in IE 9. - function splitDataNode(node, index) { - var newNode = node.cloneNode(false); - newNode.deleteData(0, index); - node.deleteData(index, node.length - index); - insertAfter(newNode, node); - return newNode; - } - - function getDocument(node) { - if (node.nodeType == 9) { - return node; - } else if (typeof node.ownerDocument != UNDEF) { - return node.ownerDocument; - } else if (typeof node.document != UNDEF) { - return node.document; - } else if (node.parentNode) { - return getDocument(node.parentNode); - } else { - throw new Error("getDocument: no document found for node"); - } - } - - function getWindow(node) { - var doc = getDocument(node); - if (typeof doc.defaultView != UNDEF) { - return doc.defaultView; - } else if (typeof doc.parentWindow != UNDEF) { - return doc.parentWindow; - } else { - throw new Error("Cannot get a window object for node"); - } - } - - function getIframeDocument(iframeEl) { - if (typeof iframeEl.contentDocument != UNDEF) { - return iframeEl.contentDocument; - } else if (typeof iframeEl.contentWindow != UNDEF) { - return iframeEl.contentWindow.document; - } else { - throw new Error("getIframeWindow: No Document object found for iframe element"); - } - } - - function getIframeWindow(iframeEl) { - if (typeof iframeEl.contentWindow != UNDEF) { - return iframeEl.contentWindow; - } else if (typeof iframeEl.contentDocument != UNDEF) { - return iframeEl.contentDocument.defaultView; - } else { - throw new Error("getIframeWindow: No Window object found for iframe element"); - } - } - - function getBody(doc) { - return util.isHostObject(doc, "body") ? doc.body : doc.getElementsByTagName("body")[0]; - } - - function getRootContainer(node) { - var parent; - while ( (parent = node.parentNode) ) { - node = parent; - } - return node; - } - - function comparePoints(nodeA, offsetA, nodeB, offsetB) { - // See http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Comparing - var nodeC, root, childA, childB, n; - if (nodeA == nodeB) { - - // Case 1: nodes are the same - return offsetA === offsetB ? 0 : (offsetA < offsetB) ? -1 : 1; - } else if ( (nodeC = getClosestAncestorIn(nodeB, nodeA, true)) ) { - - // Case 2: node C (container B or an ancestor) is a child node of A - return offsetA <= getNodeIndex(nodeC) ? -1 : 1; - } else if ( (nodeC = getClosestAncestorIn(nodeA, nodeB, true)) ) { - - // Case 3: node C (container A or an ancestor) is a child node of B - return getNodeIndex(nodeC) < offsetB ? -1 : 1; - } else { - - // Case 4: containers are siblings or descendants of siblings - root = getCommonAncestor(nodeA, nodeB); - childA = (nodeA === root) ? root : getClosestAncestorIn(nodeA, root, true); - childB = (nodeB === root) ? root : getClosestAncestorIn(nodeB, root, true); - - if (childA === childB) { - // This shouldn't be possible - - throw new Error("comparePoints got to case 4 and childA and childB are the same!"); - } else { - n = root.firstChild; - while (n) { - if (n === childA) { - return -1; - } else if (n === childB) { - return 1; - } - n = n.nextSibling; - } - throw new Error("Should not be here!"); - } - } - } - - function fragmentFromNodeChildren(node) { - var fragment = getDocument(node).createDocumentFragment(), child; - while ( (child = node.firstChild) ) { - fragment.appendChild(child); - } - return fragment; - } - - function inspectNode(node) { - if (!node) { - return "[No node]"; - } - if (isCharacterDataNode(node)) { - return '"' + node.data + '"'; - } else if (node.nodeType == 1) { - var idAttr = node.id ? ' id="' + node.id + '"' : ""; - return "<" + node.nodeName + idAttr + ">[" + node.childNodes.length + "]"; - } else { - return node.nodeName; - } - } - - /** - * @constructor - */ - function NodeIterator(root) { - this.root = root; - this._next = root; - } - - NodeIterator.prototype = { - _current: null, - - hasNext: function() { - return !!this._next; - }, - - next: function() { - var n = this._current = this._next; - var child, next; - if (this._current) { - child = n.firstChild; - if (child) { - this._next = child; - } else { - next = null; - while ((n !== this.root) && !(next = n.nextSibling)) { - n = n.parentNode; - } - this._next = next; - } - } - return this._current; - }, - - detach: function() { - this._current = this._next = this.root = null; - } - }; - - function createIterator(root) { - return new NodeIterator(root); - } - - /** - * @constructor - */ - function DomPosition(node, offset) { - this.node = node; - this.offset = offset; - } - - DomPosition.prototype = { - equals: function(pos) { - return this.node === pos.node & this.offset == pos.offset; - }, - - inspect: function() { - return "[DomPosition(" + inspectNode(this.node) + ":" + this.offset + ")]"; - } - }; - - /** - * @constructor - */ - function DOMException(codeName) { - this.code = this[codeName]; - this.codeName = codeName; - this.message = "DOMException: " + this.codeName; - } - - DOMException.prototype = { - INDEX_SIZE_ERR: 1, - HIERARCHY_REQUEST_ERR: 3, - WRONG_DOCUMENT_ERR: 4, - NO_MODIFICATION_ALLOWED_ERR: 7, - NOT_FOUND_ERR: 8, - NOT_SUPPORTED_ERR: 9, - INVALID_STATE_ERR: 11 - }; - - DOMException.prototype.toString = function() { - return this.message; - }; - - api.dom = { - arrayContains: arrayContains, - isHtmlNamespace: isHtmlNamespace, - parentElement: parentElement, - getNodeIndex: getNodeIndex, - getNodeLength: getNodeLength, - getCommonAncestor: getCommonAncestor, - isAncestorOf: isAncestorOf, - getClosestAncestorIn: getClosestAncestorIn, - isCharacterDataNode: isCharacterDataNode, - insertAfter: insertAfter, - splitDataNode: splitDataNode, - getDocument: getDocument, - getWindow: getWindow, - getIframeWindow: getIframeWindow, - getIframeDocument: getIframeDocument, - getBody: getBody, - getRootContainer: getRootContainer, - comparePoints: comparePoints, - inspectNode: inspectNode, - fragmentFromNodeChildren: fragmentFromNodeChildren, - createIterator: createIterator, - DomPosition: DomPosition - }; - - api.DOMException = DOMException; -});rangy.createModule("DomRange", function(api, module) { - api.requireModules( ["DomUtil"] ); - - - var dom = api.dom; - var DomPosition = dom.DomPosition; - var DOMException = api.DOMException; - - /*----------------------------------------------------------------------------------------------------------------*/ - - // Utility functions - - function isNonTextPartiallySelected(node, range) { - return (node.nodeType != 3) && - (dom.isAncestorOf(node, range.startContainer, true) || dom.isAncestorOf(node, range.endContainer, true)); - } - - function getRangeDocument(range) { - return dom.getDocument(range.startContainer); - } - - function dispatchEvent(range, type, args) { - var listeners = range._listeners[type]; - if (listeners) { - for (var i = 0, len = listeners.length; i < len; ++i) { - listeners[i].call(range, {target: range, args: args}); - } - } - } - - function getBoundaryBeforeNode(node) { - return new DomPosition(node.parentNode, dom.getNodeIndex(node)); - } - - function getBoundaryAfterNode(node) { - return new DomPosition(node.parentNode, dom.getNodeIndex(node) + 1); - } - - function insertNodeAtPosition(node, n, o) { - var firstNodeInserted = node.nodeType == 11 ? node.firstChild : node; - if (dom.isCharacterDataNode(n)) { - if (o == n.length) { - dom.insertAfter(node, n); - } else { - n.parentNode.insertBefore(node, o == 0 ? n : dom.splitDataNode(n, o)); - } - } else if (o >= n.childNodes.length) { - n.appendChild(node); - } else { - n.insertBefore(node, n.childNodes[o]); - } - return firstNodeInserted; - } - - function cloneSubtree(iterator) { - var partiallySelected; - for (var node, frag = getRangeDocument(iterator.range).createDocumentFragment(), subIterator; node = iterator.next(); ) { - partiallySelected = iterator.isPartiallySelectedSubtree(); - - node = node.cloneNode(!partiallySelected); - if (partiallySelected) { - subIterator = iterator.getSubtreeIterator(); - node.appendChild(cloneSubtree(subIterator)); - subIterator.detach(true); - } - - if (node.nodeType == 10) { // DocumentType - throw new DOMException("HIERARCHY_REQUEST_ERR"); - } - frag.appendChild(node); - } - return frag; - } - - function iterateSubtree(rangeIterator, func, iteratorState) { - var it, n; - iteratorState = iteratorState || { stop: false }; - for (var node, subRangeIterator; node = rangeIterator.next(); ) { - //log.debug("iterateSubtree, partially selected: " + rangeIterator.isPartiallySelectedSubtree(), nodeToString(node)); - if (rangeIterator.isPartiallySelectedSubtree()) { - // The node is partially selected by the Range, so we can use a new RangeIterator on the portion of the - // node selected by the Range. - if (func(node) === false) { - iteratorState.stop = true; - return; - } else { - subRangeIterator = rangeIterator.getSubtreeIterator(); - iterateSubtree(subRangeIterator, func, iteratorState); - subRangeIterator.detach(true); - if (iteratorState.stop) { - return; - } - } - } else { - // The whole node is selected, so we can use efficient DOM iteration to iterate over the node and its - // descendant - it = dom.createIterator(node); - while ( (n = it.next()) ) { - if (func(n) === false) { - iteratorState.stop = true; - return; - } - } - } - } - } - - function deleteSubtree(iterator) { - var subIterator; - while (iterator.next()) { - if (iterator.isPartiallySelectedSubtree()) { - subIterator = iterator.getSubtreeIterator(); - deleteSubtree(subIterator); - subIterator.detach(true); - } else { - iterator.remove(); - } - } - } - - function extractSubtree(iterator) { - - for (var node, frag = getRangeDocument(iterator.range).createDocumentFragment(), subIterator; node = iterator.next(); ) { - - - if (iterator.isPartiallySelectedSubtree()) { - node = node.cloneNode(false); - subIterator = iterator.getSubtreeIterator(); - node.appendChild(extractSubtree(subIterator)); - subIterator.detach(true); - } else { - iterator.remove(); - } - if (node.nodeType == 10) { // DocumentType - throw new DOMException("HIERARCHY_REQUEST_ERR"); - } - frag.appendChild(node); - } - return frag; - } - - function getNodesInRange(range, nodeTypes, filter) { - //log.info("getNodesInRange, " + nodeTypes.join(",")); - var filterNodeTypes = !!(nodeTypes && nodeTypes.length), regex; - var filterExists = !!filter; - if (filterNodeTypes) { - regex = new RegExp("^(" + nodeTypes.join("|") + ")$"); - } - - var nodes = []; - iterateSubtree(new RangeIterator(range, false), function(node) { - if ((!filterNodeTypes || regex.test(node.nodeType)) && (!filterExists || filter(node))) { - nodes.push(node); - } - }); - return nodes; - } - - function inspect(range) { - var name = (typeof range.getName == "undefined") ? "Range" : range.getName(); - return "[" + name + "(" + dom.inspectNode(range.startContainer) + ":" + range.startOffset + ", " + - dom.inspectNode(range.endContainer) + ":" + range.endOffset + ")]"; - } - - /*----------------------------------------------------------------------------------------------------------------*/ - - // RangeIterator code partially borrows from IERange by Tim Ryan (http://github.com/timcameronryan/IERange) - - /** - * @constructor - */ - function RangeIterator(range, clonePartiallySelectedTextNodes) { - this.range = range; - this.clonePartiallySelectedTextNodes = clonePartiallySelectedTextNodes; - - - - if (!range.collapsed) { - this.sc = range.startContainer; - this.so = range.startOffset; - this.ec = range.endContainer; - this.eo = range.endOffset; - var root = range.commonAncestorContainer; - - if (this.sc === this.ec && dom.isCharacterDataNode(this.sc)) { - this.isSingleCharacterDataNode = true; - this._first = this._last = this._next = this.sc; - } else { - this._first = this._next = (this.sc === root && !dom.isCharacterDataNode(this.sc)) ? - this.sc.childNodes[this.so] : dom.getClosestAncestorIn(this.sc, root, true); - this._last = (this.ec === root && !dom.isCharacterDataNode(this.ec)) ? - this.ec.childNodes[this.eo - 1] : dom.getClosestAncestorIn(this.ec, root, true); - } - - } - } - - RangeIterator.prototype = { - _current: null, - _next: null, - _first: null, - _last: null, - isSingleCharacterDataNode: false, - - reset: function() { - this._current = null; - this._next = this._first; - }, - - hasNext: function() { - return !!this._next; - }, - - next: function() { - // Move to next node - var current = this._current = this._next; - if (current) { - this._next = (current !== this._last) ? current.nextSibling : null; - - // Check for partially selected text nodes - if (dom.isCharacterDataNode(current) && this.clonePartiallySelectedTextNodes) { - if (current === this.ec) { - - (current = current.cloneNode(true)).deleteData(this.eo, current.length - this.eo); - } - if (this._current === this.sc) { - - (current = current.cloneNode(true)).deleteData(0, this.so); - } - } - } - - return current; - }, - - remove: function() { - var current = this._current, start, end; - - if (dom.isCharacterDataNode(current) && (current === this.sc || current === this.ec)) { - start = (current === this.sc) ? this.so : 0; - end = (current === this.ec) ? this.eo : current.length; - if (start != end) { - current.deleteData(start, end - start); - } - } else { - if (current.parentNode) { - current.parentNode.removeChild(current); - } else { - - } - } - }, - - // Checks if the current node is partially selected - isPartiallySelectedSubtree: function() { - var current = this._current; - return isNonTextPartiallySelected(current, this.range); - }, - - getSubtreeIterator: function() { - var subRange; - if (this.isSingleCharacterDataNode) { - subRange = this.range.cloneRange(); - subRange.collapse(); - } else { - subRange = new Range(getRangeDocument(this.range)); - var current = this._current; - var startContainer = current, startOffset = 0, endContainer = current, endOffset = dom.getNodeLength(current); - - if (dom.isAncestorOf(current, this.sc, true)) { - startContainer = this.sc; - startOffset = this.so; - } - if (dom.isAncestorOf(current, this.ec, true)) { - endContainer = this.ec; - endOffset = this.eo; - } - - updateBoundaries(subRange, startContainer, startOffset, endContainer, endOffset); - } - return new RangeIterator(subRange, this.clonePartiallySelectedTextNodes); - }, - - detach: function(detachRange) { - if (detachRange) { - this.range.detach(); - } - this.range = this._current = this._next = this._first = this._last = this.sc = this.so = this.ec = this.eo = null; - } - }; - - /*----------------------------------------------------------------------------------------------------------------*/ - - // Exceptions - - /** - * @constructor - */ - function RangeException(codeName) { - this.code = this[codeName]; - this.codeName = codeName; - this.message = "RangeException: " + this.codeName; - } - - RangeException.prototype = { - BAD_BOUNDARYPOINTS_ERR: 1, - INVALID_NODE_TYPE_ERR: 2 - }; - - RangeException.prototype.toString = function() { - return this.message; - }; - - /*----------------------------------------------------------------------------------------------------------------*/ - - /** - * Currently iterates through all nodes in the range on creation until I think of a decent way to do it - * TODO: Look into making this a proper iterator, not requiring preloading everything first - * @constructor - */ - function RangeNodeIterator(range, nodeTypes, filter) { - this.nodes = getNodesInRange(range, nodeTypes, filter); - this._next = this.nodes[0]; - this._position = 0; - } - - RangeNodeIterator.prototype = { - _current: null, - - hasNext: function() { - return !!this._next; - }, - - next: function() { - this._current = this._next; - this._next = this.nodes[ ++this._position ]; - return this._current; - }, - - detach: function() { - this._current = this._next = this.nodes = null; - } - }; - - var beforeAfterNodeTypes = [1, 3, 4, 5, 7, 8, 10]; - var rootContainerNodeTypes = [2, 9, 11]; - var readonlyNodeTypes = [5, 6, 10, 12]; - var insertableNodeTypes = [1, 3, 4, 5, 7, 8, 10, 11]; - var surroundNodeTypes = [1, 3, 4, 5, 7, 8]; - - function createAncestorFinder(nodeTypes) { - return function(node, selfIsAncestor) { - var t, n = selfIsAncestor ? node : node.parentNode; - while (n) { - t = n.nodeType; - if (dom.arrayContains(nodeTypes, t)) { - return n; - } - n = n.parentNode; - } - return null; - }; - } - - var getRootContainer = dom.getRootContainer; - var getDocumentOrFragmentContainer = createAncestorFinder( [9, 11] ); - var getReadonlyAncestor = createAncestorFinder(readonlyNodeTypes); - var getDocTypeNotationEntityAncestor = createAncestorFinder( [6, 10, 12] ); - - function assertNoDocTypeNotationEntityAncestor(node, allowSelf) { - if (getDocTypeNotationEntityAncestor(node, allowSelf)) { - throw new RangeException("INVALID_NODE_TYPE_ERR"); - } - } - - function assertNotDetached(range) { - if (!range.startContainer) { - throw new DOMException("INVALID_STATE_ERR"); - } - } - - function assertValidNodeType(node, invalidTypes) { - if (!dom.arrayContains(invalidTypes, node.nodeType)) { - throw new RangeException("INVALID_NODE_TYPE_ERR"); - } - } - - function assertValidOffset(node, offset) { - if (offset < 0 || offset > (dom.isCharacterDataNode(node) ? node.length : node.childNodes.length)) { - throw new DOMException("INDEX_SIZE_ERR"); - } - } - - function assertSameDocumentOrFragment(node1, node2) { - if (getDocumentOrFragmentContainer(node1, true) !== getDocumentOrFragmentContainer(node2, true)) { - throw new DOMException("WRONG_DOCUMENT_ERR"); - } - } - - function assertNodeNotReadOnly(node) { - if (getReadonlyAncestor(node, true)) { - throw new DOMException("NO_MODIFICATION_ALLOWED_ERR"); - } - } - - function assertNode(node, codeName) { - if (!node) { - throw new DOMException(codeName); - } - } - - function isOrphan(node) { - return !dom.arrayContains(rootContainerNodeTypes, node.nodeType) && !getDocumentOrFragmentContainer(node, true); - } - - function isValidOffset(node, offset) { - return offset <= (dom.isCharacterDataNode(node) ? node.length : node.childNodes.length); - } - - function assertRangeValid(range) { - assertNotDetached(range); - if (isOrphan(range.startContainer) || isOrphan(range.endContainer) || - !isValidOffset(range.startContainer, range.startOffset) || - !isValidOffset(range.endContainer, range.endOffset)) { - throw new Error("Range error: Range is no longer valid after DOM mutation (" + range.inspect() + ")"); - } - } - - /*----------------------------------------------------------------------------------------------------------------*/ - - // Test the browser's innerHTML support to decide how to implement createContextualFragment - var styleEl = document.createElement("style"); - var htmlParsingConforms = false; - try { - styleEl.innerHTML = "x"; - htmlParsingConforms = (styleEl.firstChild.nodeType == 3); // Opera incorrectly creates an element node - } catch (e) { - // IE 6 and 7 throw - } - - api.features.htmlParsingConforms = htmlParsingConforms; - - var createContextualFragment = htmlParsingConforms ? - - // Implementation as per HTML parsing spec, trusting in the browser's implementation of innerHTML. See - // discussion and base code for this implementation at issue 67. - // Spec: http://html5.org/specs/dom-parsing.html#extensions-to-the-range-interface - // Thanks to Aleks Williams. - function(fragmentStr) { - // "Let node the context object's start's node." - var node = this.startContainer; - var doc = dom.getDocument(node); - - // "If the context object's start's node is null, raise an INVALID_STATE_ERR - // exception and abort these steps." - if (!node) { - throw new DOMException("INVALID_STATE_ERR"); - } - - // "Let element be as follows, depending on node's interface:" - // Document, Document Fragment: null - var el = null; - - // "Element: node" - if (node.nodeType == 1) { - el = node; - - // "Text, Comment: node's parentElement" - } else if (dom.isCharacterDataNode(node)) { - el = dom.parentElement(node); - } - - // "If either element is null or element's ownerDocument is an HTML document - // and element's local name is "html" and element's namespace is the HTML - // namespace" - if (el === null || ( - el.nodeName == "HTML" - && dom.isHtmlNamespace(dom.getDocument(el).documentElement) - && dom.isHtmlNamespace(el) - )) { - - // "let element be a new Element with "body" as its local name and the HTML - // namespace as its namespace."" - el = doc.createElement("body"); - } else { - el = el.cloneNode(false); - } - - // "If the node's document is an HTML document: Invoke the HTML fragment parsing algorithm." - // "If the node's document is an XML document: Invoke the XML fragment parsing algorithm." - // "In either case, the algorithm must be invoked with fragment as the input - // and element as the context element." - el.innerHTML = fragmentStr; - - // "If this raises an exception, then abort these steps. Otherwise, let new - // children be the nodes returned." - - // "Let fragment be a new DocumentFragment." - // "Append all new children to fragment." - // "Return fragment." - return dom.fragmentFromNodeChildren(el); - } : - - // In this case, innerHTML cannot be trusted, so fall back to a simpler, non-conformant implementation that - // previous versions of Rangy used (with the exception of using a body element rather than a div) - function(fragmentStr) { - assertNotDetached(this); - var doc = getRangeDocument(this); - var el = doc.createElement("body"); - el.innerHTML = fragmentStr; - - return dom.fragmentFromNodeChildren(el); - }; - - /*----------------------------------------------------------------------------------------------------------------*/ - - var rangeProperties = ["startContainer", "startOffset", "endContainer", "endOffset", "collapsed", - "commonAncestorContainer"]; - - var s2s = 0, s2e = 1, e2e = 2, e2s = 3; - var n_b = 0, n_a = 1, n_b_a = 2, n_i = 3; - - function RangePrototype() {} - - RangePrototype.prototype = { - attachListener: function(type, listener) { - this._listeners[type].push(listener); - }, - - compareBoundaryPoints: function(how, range) { - assertRangeValid(this); - assertSameDocumentOrFragment(this.startContainer, range.startContainer); - - var nodeA, offsetA, nodeB, offsetB; - var prefixA = (how == e2s || how == s2s) ? "start" : "end"; - var prefixB = (how == s2e || how == s2s) ? "start" : "end"; - nodeA = this[prefixA + "Container"]; - offsetA = this[prefixA + "Offset"]; - nodeB = range[prefixB + "Container"]; - offsetB = range[prefixB + "Offset"]; - return dom.comparePoints(nodeA, offsetA, nodeB, offsetB); - }, - - insertNode: function(node) { - assertRangeValid(this); - assertValidNodeType(node, insertableNodeTypes); - assertNodeNotReadOnly(this.startContainer); - - if (dom.isAncestorOf(node, this.startContainer, true)) { - throw new DOMException("HIERARCHY_REQUEST_ERR"); - } - - // No check for whether the container of the start of the Range is of a type that does not allow - // children of the type of node: the browser's DOM implementation should do this for us when we attempt - // to add the node - - var firstNodeInserted = insertNodeAtPosition(node, this.startContainer, this.startOffset); - this.setStartBefore(firstNodeInserted); - }, - - cloneContents: function() { - assertRangeValid(this); - - var clone, frag; - if (this.collapsed) { - return getRangeDocument(this).createDocumentFragment(); - } else { - if (this.startContainer === this.endContainer && dom.isCharacterDataNode(this.startContainer)) { - clone = this.startContainer.cloneNode(true); - clone.data = clone.data.slice(this.startOffset, this.endOffset); - frag = getRangeDocument(this).createDocumentFragment(); - frag.appendChild(clone); - return frag; - } else { - var iterator = new RangeIterator(this, true); - clone = cloneSubtree(iterator); - iterator.detach(); - } - return clone; - } - }, - - canSurroundContents: function() { - assertRangeValid(this); - assertNodeNotReadOnly(this.startContainer); - assertNodeNotReadOnly(this.endContainer); - - // Check if the contents can be surrounded. Specifically, this means whether the range partially selects - // no non-text nodes. - var iterator = new RangeIterator(this, true); - var boundariesInvalid = (iterator._first && (isNonTextPartiallySelected(iterator._first, this)) || - (iterator._last && isNonTextPartiallySelected(iterator._last, this))); - iterator.detach(); - return !boundariesInvalid; - }, - - surroundContents: function(node) { - assertValidNodeType(node, surroundNodeTypes); - - if (!this.canSurroundContents()) { - throw new RangeException("BAD_BOUNDARYPOINTS_ERR"); - } - - // Extract the contents - var content = this.extractContents(); - - // Clear the children of the node - if (node.hasChildNodes()) { - while (node.lastChild) { - node.removeChild(node.lastChild); - } - } - - // Insert the new node and add the extracted contents - insertNodeAtPosition(node, this.startContainer, this.startOffset); - node.appendChild(content); - - this.selectNode(node); - }, - - cloneRange: function() { - assertRangeValid(this); - var range = new Range(getRangeDocument(this)); - var i = rangeProperties.length, prop; - while (i--) { - prop = rangeProperties[i]; - range[prop] = this[prop]; - } - return range; - }, - - toString: function() { - assertRangeValid(this); - var sc = this.startContainer; - if (sc === this.endContainer && dom.isCharacterDataNode(sc)) { - return (sc.nodeType == 3 || sc.nodeType == 4) ? sc.data.slice(this.startOffset, this.endOffset) : ""; - } else { - var textBits = [], iterator = new RangeIterator(this, true); - - iterateSubtree(iterator, function(node) { - // Accept only text or CDATA nodes, not comments - - if (node.nodeType == 3 || node.nodeType == 4) { - textBits.push(node.data); - } - }); - iterator.detach(); - return textBits.join(""); - } - }, - - // The methods below are all non-standard. The following batch were introduced by Mozilla but have since - // been removed from Mozilla. - - compareNode: function(node) { - assertRangeValid(this); - - var parent = node.parentNode; - var nodeIndex = dom.getNodeIndex(node); - - if (!parent) { - throw new DOMException("NOT_FOUND_ERR"); - } - - var startComparison = this.comparePoint(parent, nodeIndex), - endComparison = this.comparePoint(parent, nodeIndex + 1); - - if (startComparison < 0) { // Node starts before - return (endComparison > 0) ? n_b_a : n_b; - } else { - return (endComparison > 0) ? n_a : n_i; - } - }, - - comparePoint: function(node, offset) { - assertRangeValid(this); - assertNode(node, "HIERARCHY_REQUEST_ERR"); - assertSameDocumentOrFragment(node, this.startContainer); - - if (dom.comparePoints(node, offset, this.startContainer, this.startOffset) < 0) { - return -1; - } else if (dom.comparePoints(node, offset, this.endContainer, this.endOffset) > 0) { - return 1; - } - return 0; - }, - - createContextualFragment: createContextualFragment, - - toHtml: function() { - assertRangeValid(this); - var container = getRangeDocument(this).createElement("div"); - container.appendChild(this.cloneContents()); - return container.innerHTML; - }, - - // touchingIsIntersecting determines whether this method considers a node that borders a range intersects - // with it (as in WebKit) or not (as in Gecko pre-1.9, and the default) - intersectsNode: function(node, touchingIsIntersecting) { - assertRangeValid(this); - assertNode(node, "NOT_FOUND_ERR"); - if (dom.getDocument(node) !== getRangeDocument(this)) { - return false; - } - - var parent = node.parentNode, offset = dom.getNodeIndex(node); - assertNode(parent, "NOT_FOUND_ERR"); - - var startComparison = dom.comparePoints(parent, offset, this.endContainer, this.endOffset), - endComparison = dom.comparePoints(parent, offset + 1, this.startContainer, this.startOffset); - - return touchingIsIntersecting ? startComparison <= 0 && endComparison >= 0 : startComparison < 0 && endComparison > 0; - }, - - - isPointInRange: function(node, offset) { - assertRangeValid(this); - assertNode(node, "HIERARCHY_REQUEST_ERR"); - assertSameDocumentOrFragment(node, this.startContainer); - - return (dom.comparePoints(node, offset, this.startContainer, this.startOffset) >= 0) && - (dom.comparePoints(node, offset, this.endContainer, this.endOffset) <= 0); - }, - - // The methods below are non-standard and invented by me. - - // Sharing a boundary start-to-end or end-to-start does not count as intersection. - intersectsRange: function(range, touchingIsIntersecting) { - assertRangeValid(this); - - if (getRangeDocument(range) != getRangeDocument(this)) { - throw new DOMException("WRONG_DOCUMENT_ERR"); - } - - var startComparison = dom.comparePoints(this.startContainer, this.startOffset, range.endContainer, range.endOffset), - endComparison = dom.comparePoints(this.endContainer, this.endOffset, range.startContainer, range.startOffset); - - return touchingIsIntersecting ? startComparison <= 0 && endComparison >= 0 : startComparison < 0 && endComparison > 0; - }, - - intersection: function(range) { - if (this.intersectsRange(range)) { - var startComparison = dom.comparePoints(this.startContainer, this.startOffset, range.startContainer, range.startOffset), - endComparison = dom.comparePoints(this.endContainer, this.endOffset, range.endContainer, range.endOffset); - - var intersectionRange = this.cloneRange(); - - if (startComparison == -1) { - intersectionRange.setStart(range.startContainer, range.startOffset); - } - if (endComparison == 1) { - intersectionRange.setEnd(range.endContainer, range.endOffset); - } - return intersectionRange; - } - return null; - }, - - union: function(range) { - if (this.intersectsRange(range, true)) { - var unionRange = this.cloneRange(); - if (dom.comparePoints(range.startContainer, range.startOffset, this.startContainer, this.startOffset) == -1) { - unionRange.setStart(range.startContainer, range.startOffset); - } - if (dom.comparePoints(range.endContainer, range.endOffset, this.endContainer, this.endOffset) == 1) { - unionRange.setEnd(range.endContainer, range.endOffset); - } - return unionRange; - } else { - throw new RangeException("Ranges do not intersect"); - } - }, - - containsNode: function(node, allowPartial) { - if (allowPartial) { - return this.intersectsNode(node, false); - } else { - return this.compareNode(node) == n_i; - } - }, - - containsNodeContents: function(node) { - return this.comparePoint(node, 0) >= 0 && this.comparePoint(node, dom.getNodeLength(node)) <= 0; - }, - - containsRange: function(range) { - return this.intersection(range).equals(range); - }, - - containsNodeText: function(node) { - var nodeRange = this.cloneRange(); - nodeRange.selectNode(node); - var textNodes = nodeRange.getNodes([3]); - if (textNodes.length > 0) { - nodeRange.setStart(textNodes[0], 0); - var lastTextNode = textNodes.pop(); - nodeRange.setEnd(lastTextNode, lastTextNode.length); - var contains = this.containsRange(nodeRange); - nodeRange.detach(); - return contains; - } else { - return this.containsNodeContents(node); - } - }, - - createNodeIterator: function(nodeTypes, filter) { - assertRangeValid(this); - return new RangeNodeIterator(this, nodeTypes, filter); - }, - - getNodes: function(nodeTypes, filter) { - assertRangeValid(this); - return getNodesInRange(this, nodeTypes, filter); - }, - - getDocument: function() { - return getRangeDocument(this); - }, - - collapseBefore: function(node) { - assertNotDetached(this); - - this.setEndBefore(node); - this.collapse(false); - }, - - collapseAfter: function(node) { - assertNotDetached(this); - - this.setStartAfter(node); - this.collapse(true); - }, - - getName: function() { - return "DomRange"; - }, - - equals: function(range) { - return Range.rangesEqual(this, range); - }, - - inspect: function() { - return inspect(this); - } - }; - - function copyComparisonConstantsToObject(obj) { - obj.START_TO_START = s2s; - obj.START_TO_END = s2e; - obj.END_TO_END = e2e; - obj.END_TO_START = e2s; - - obj.NODE_BEFORE = n_b; - obj.NODE_AFTER = n_a; - obj.NODE_BEFORE_AND_AFTER = n_b_a; - obj.NODE_INSIDE = n_i; - } - - function copyComparisonConstants(constructor) { - copyComparisonConstantsToObject(constructor); - copyComparisonConstantsToObject(constructor.prototype); - } - - function createRangeContentRemover(remover, boundaryUpdater) { - return function() { - assertRangeValid(this); - - var sc = this.startContainer, so = this.startOffset, root = this.commonAncestorContainer; - - var iterator = new RangeIterator(this, true); - - // Work out where to position the range after content removal - var node, boundary; - if (sc !== root) { - node = dom.getClosestAncestorIn(sc, root, true); - boundary = getBoundaryAfterNode(node); - sc = boundary.node; - so = boundary.offset; - } - - // Check none of the range is read-only - iterateSubtree(iterator, assertNodeNotReadOnly); - - iterator.reset(); - - // Remove the content - var returnValue = remover(iterator); - iterator.detach(); - - // Move to the new position - boundaryUpdater(this, sc, so, sc, so); - - return returnValue; - }; - } - - function createPrototypeRange(constructor, boundaryUpdater, detacher) { - function createBeforeAfterNodeSetter(isBefore, isStart) { - return function(node) { - assertNotDetached(this); - assertValidNodeType(node, beforeAfterNodeTypes); - assertValidNodeType(getRootContainer(node), rootContainerNodeTypes); - - var boundary = (isBefore ? getBoundaryBeforeNode : getBoundaryAfterNode)(node); - (isStart ? setRangeStart : setRangeEnd)(this, boundary.node, boundary.offset); - }; - } - - function setRangeStart(range, node, offset) { - var ec = range.endContainer, eo = range.endOffset; - if (node !== range.startContainer || offset !== range.startOffset) { - // Check the root containers of the range and the new boundary, and also check whether the new boundary - // is after the current end. In either case, collapse the range to the new position - if (getRootContainer(node) != getRootContainer(ec) || dom.comparePoints(node, offset, ec, eo) == 1) { - ec = node; - eo = offset; - } - boundaryUpdater(range, node, offset, ec, eo); - } - } - - function setRangeEnd(range, node, offset) { - var sc = range.startContainer, so = range.startOffset; - if (node !== range.endContainer || offset !== range.endOffset) { - // Check the root containers of the range and the new boundary, and also check whether the new boundary - // is after the current end. In either case, collapse the range to the new position - if (getRootContainer(node) != getRootContainer(sc) || dom.comparePoints(node, offset, sc, so) == -1) { - sc = node; - so = offset; - } - boundaryUpdater(range, sc, so, node, offset); - } - } - - function setRangeStartAndEnd(range, node, offset) { - if (node !== range.startContainer || offset !== range.startOffset || node !== range.endContainer || offset !== range.endOffset) { - boundaryUpdater(range, node, offset, node, offset); - } - } - - constructor.prototype = new RangePrototype(); - - api.util.extend(constructor.prototype, { - setStart: function(node, offset) { - assertNotDetached(this); - assertNoDocTypeNotationEntityAncestor(node, true); - assertValidOffset(node, offset); - - setRangeStart(this, node, offset); - }, - - setEnd: function(node, offset) { - assertNotDetached(this); - assertNoDocTypeNotationEntityAncestor(node, true); - assertValidOffset(node, offset); - - setRangeEnd(this, node, offset); - }, - - setStartBefore: createBeforeAfterNodeSetter(true, true), - setStartAfter: createBeforeAfterNodeSetter(false, true), - setEndBefore: createBeforeAfterNodeSetter(true, false), - setEndAfter: createBeforeAfterNodeSetter(false, false), - - collapse: function(isStart) { - assertRangeValid(this); - if (isStart) { - boundaryUpdater(this, this.startContainer, this.startOffset, this.startContainer, this.startOffset); - } else { - boundaryUpdater(this, this.endContainer, this.endOffset, this.endContainer, this.endOffset); - } - }, - - selectNodeContents: function(node) { - // This doesn't seem well specified: the spec talks only about selecting the node's contents, which - // could be taken to mean only its children. However, browsers implement this the same as selectNode for - // text nodes, so I shall do likewise - assertNotDetached(this); - assertNoDocTypeNotationEntityAncestor(node, true); - - boundaryUpdater(this, node, 0, node, dom.getNodeLength(node)); - }, - - selectNode: function(node) { - assertNotDetached(this); - assertNoDocTypeNotationEntityAncestor(node, false); - assertValidNodeType(node, beforeAfterNodeTypes); - - var start = getBoundaryBeforeNode(node), end = getBoundaryAfterNode(node); - boundaryUpdater(this, start.node, start.offset, end.node, end.offset); - }, - - extractContents: createRangeContentRemover(extractSubtree, boundaryUpdater), - - deleteContents: createRangeContentRemover(deleteSubtree, boundaryUpdater), - - canSurroundContents: function() { - assertRangeValid(this); - assertNodeNotReadOnly(this.startContainer); - assertNodeNotReadOnly(this.endContainer); - - // Check if the contents can be surrounded. Specifically, this means whether the range partially selects - // no non-text nodes. - var iterator = new RangeIterator(this, true); - var boundariesInvalid = (iterator._first && (isNonTextPartiallySelected(iterator._first, this)) || - (iterator._last && isNonTextPartiallySelected(iterator._last, this))); - iterator.detach(); - return !boundariesInvalid; - }, - - detach: function() { - detacher(this); - }, - - splitBoundaries: function() { - assertRangeValid(this); - - - var sc = this.startContainer, so = this.startOffset, ec = this.endContainer, eo = this.endOffset; - var startEndSame = (sc === ec); - - if (dom.isCharacterDataNode(ec) && eo > 0 && eo < ec.length) { - dom.splitDataNode(ec, eo); - - } - - if (dom.isCharacterDataNode(sc) && so > 0 && so < sc.length) { - - sc = dom.splitDataNode(sc, so); - if (startEndSame) { - eo -= so; - ec = sc; - } else if (ec == sc.parentNode && eo >= dom.getNodeIndex(sc)) { - eo++; - } - so = 0; - - } - boundaryUpdater(this, sc, so, ec, eo); - }, - - normalizeBoundaries: function() { - assertRangeValid(this); - - var sc = this.startContainer, so = this.startOffset, ec = this.endContainer, eo = this.endOffset; - - var mergeForward = function(node) { - var sibling = node.nextSibling; - if (sibling && sibling.nodeType == node.nodeType) { - ec = node; - eo = node.length; - node.appendData(sibling.data); - sibling.parentNode.removeChild(sibling); - } - }; - - var mergeBackward = function(node) { - var sibling = node.previousSibling; - if (sibling && sibling.nodeType == node.nodeType) { - sc = node; - var nodeLength = node.length; - so = sibling.length; - node.insertData(0, sibling.data); - sibling.parentNode.removeChild(sibling); - if (sc == ec) { - eo += so; - ec = sc; - } else if (ec == node.parentNode) { - var nodeIndex = dom.getNodeIndex(node); - if (eo == nodeIndex) { - ec = node; - eo = nodeLength; - } else if (eo > nodeIndex) { - eo--; - } - } - } - }; - - var normalizeStart = true; - - if (dom.isCharacterDataNode(ec)) { - if (ec.length == eo) { - mergeForward(ec); - } - } else { - if (eo > 0) { - var endNode = ec.childNodes[eo - 1]; - if (endNode && dom.isCharacterDataNode(endNode)) { - mergeForward(endNode); - } - } - normalizeStart = !this.collapsed; - } - - if (normalizeStart) { - if (dom.isCharacterDataNode(sc)) { - if (so == 0) { - mergeBackward(sc); - } - } else { - if (so < sc.childNodes.length) { - var startNode = sc.childNodes[so]; - if (startNode && dom.isCharacterDataNode(startNode)) { - mergeBackward(startNode); - } - } - } - } else { - sc = ec; - so = eo; - } - - boundaryUpdater(this, sc, so, ec, eo); - }, - - collapseToPoint: function(node, offset) { - assertNotDetached(this); - - assertNoDocTypeNotationEntityAncestor(node, true); - assertValidOffset(node, offset); - - setRangeStartAndEnd(this, node, offset); - } - }); - - copyComparisonConstants(constructor); - } - - /*----------------------------------------------------------------------------------------------------------------*/ - - // Updates commonAncestorContainer and collapsed after boundary change - function updateCollapsedAndCommonAncestor(range) { - range.collapsed = (range.startContainer === range.endContainer && range.startOffset === range.endOffset); - range.commonAncestorContainer = range.collapsed ? - range.startContainer : dom.getCommonAncestor(range.startContainer, range.endContainer); - } - - function updateBoundaries(range, startContainer, startOffset, endContainer, endOffset) { - var startMoved = (range.startContainer !== startContainer || range.startOffset !== startOffset); - var endMoved = (range.endContainer !== endContainer || range.endOffset !== endOffset); - - range.startContainer = startContainer; - range.startOffset = startOffset; - range.endContainer = endContainer; - range.endOffset = endOffset; - - updateCollapsedAndCommonAncestor(range); - dispatchEvent(range, "boundarychange", {startMoved: startMoved, endMoved: endMoved}); - } - - function detach(range) { - assertNotDetached(range); - range.startContainer = range.startOffset = range.endContainer = range.endOffset = null; - range.collapsed = range.commonAncestorContainer = null; - dispatchEvent(range, "detach", null); - range._listeners = null; - } - - /** - * @constructor - */ - function Range(doc) { - this.startContainer = doc; - this.startOffset = 0; - this.endContainer = doc; - this.endOffset = 0; - this._listeners = { - boundarychange: [], - detach: [] - }; - updateCollapsedAndCommonAncestor(this); - } - - createPrototypeRange(Range, updateBoundaries, detach); - - api.rangePrototype = RangePrototype.prototype; - - Range.rangeProperties = rangeProperties; - Range.RangeIterator = RangeIterator; - Range.copyComparisonConstants = copyComparisonConstants; - Range.createPrototypeRange = createPrototypeRange; - Range.inspect = inspect; - Range.getRangeDocument = getRangeDocument; - Range.rangesEqual = function(r1, r2) { - return r1.startContainer === r2.startContainer && - r1.startOffset === r2.startOffset && - r1.endContainer === r2.endContainer && - r1.endOffset === r2.endOffset; - }; - - api.DomRange = Range; - api.RangeException = RangeException; -});rangy.createModule("WrappedRange", function(api, module) { - api.requireModules( ["DomUtil", "DomRange"] ); - - /** - * @constructor - */ - var WrappedRange; - var dom = api.dom; - var DomPosition = dom.DomPosition; - var DomRange = api.DomRange; - - - - /*----------------------------------------------------------------------------------------------------------------*/ - - /* - This is a workaround for a bug where IE returns the wrong container element from the TextRange's parentElement() - method. For example, in the following (where pipes denote the selection boundaries): - -
  • | a
  • b |
- - var range = document.selection.createRange(); - alert(range.parentElement().id); // Should alert "ul" but alerts "b" - - This method returns the common ancestor node of the following: - - the parentElement() of the textRange - - the parentElement() of the textRange after calling collapse(true) - - the parentElement() of the textRange after calling collapse(false) - */ - function getTextRangeContainerElement(textRange) { - var parentEl = textRange.parentElement(); - - var range = textRange.duplicate(); - range.collapse(true); - var startEl = range.parentElement(); - range = textRange.duplicate(); - range.collapse(false); - var endEl = range.parentElement(); - var startEndContainer = (startEl == endEl) ? startEl : dom.getCommonAncestor(startEl, endEl); - - return startEndContainer == parentEl ? startEndContainer : dom.getCommonAncestor(parentEl, startEndContainer); - } - - function textRangeIsCollapsed(textRange) { - return textRange.compareEndPoints("StartToEnd", textRange) == 0; - } - - // Gets the boundary of a TextRange expressed as a node and an offset within that node. This function started out as - // an improved version of code found in Tim Cameron Ryan's IERange (http://code.google.com/p/ierange/) but has - // grown, fixing problems with line breaks in preformatted text, adding workaround for IE TextRange bugs, handling - // for inputs and images, plus optimizations. - function getTextRangeBoundaryPosition(textRange, wholeRangeContainerElement, isStart, isCollapsed) { - var workingRange = textRange.duplicate(); - - workingRange.collapse(isStart); - var containerElement = workingRange.parentElement(); - - // Sometimes collapsing a TextRange that's at the start of a text node can move it into the previous node, so - // check for that - // TODO: Find out when. Workaround for wholeRangeContainerElement may break this - if (!dom.isAncestorOf(wholeRangeContainerElement, containerElement, true)) { - containerElement = wholeRangeContainerElement; - - } - - - - // Deal with nodes that cannot "contain rich HTML markup". In practice, this means form inputs, images and - // similar. See http://msdn.microsoft.com/en-us/library/aa703950%28VS.85%29.aspx - if (!containerElement.canHaveHTML) { - return new DomPosition(containerElement.parentNode, dom.getNodeIndex(containerElement)); - } - - var workingNode = dom.getDocument(containerElement).createElement("span"); - var comparison, workingComparisonType = isStart ? "StartToStart" : "StartToEnd"; - var previousNode, nextNode, boundaryPosition, boundaryNode; - - // Move the working range through the container's children, starting at the end and working backwards, until the - // working range reaches or goes past the boundary we're interested in - do { - containerElement.insertBefore(workingNode, workingNode.previousSibling); - workingRange.moveToElementText(workingNode); - } while ( (comparison = workingRange.compareEndPoints(workingComparisonType, textRange)) > 0 && - workingNode.previousSibling); - - // We've now reached or gone past the boundary of the text range we're interested in - // so have identified the node we want - boundaryNode = workingNode.nextSibling; - - if (comparison == -1 && boundaryNode && dom.isCharacterDataNode(boundaryNode)) { - // This is a character data node (text, comment, cdata). The working range is collapsed at the start of the - // node containing the text range's boundary, so we move the end of the working range to the boundary point - // and measure the length of its text to get the boundary's offset within the node. - workingRange.setEndPoint(isStart ? "EndToStart" : "EndToEnd", textRange); - - - var offset; - - if (/[\r\n]/.test(boundaryNode.data)) { - /* - For the particular case of a boundary within a text node containing line breaks (within a
 element,
-                for example), we need a slightly complicated approach to get the boundary's offset in IE. The facts:
-
-                - Each line break is represented as \r in the text node's data/nodeValue properties
-                - Each line break is represented as \r\n in the TextRange's 'text' property
-                - The 'text' property of the TextRange does not contain trailing line breaks
-
-                To get round the problem presented by the final fact above, we can use the fact that TextRange's
-                moveStart() and moveEnd() methods return the actual number of characters moved, which is not necessarily
-                the same as the number of characters it was instructed to move. The simplest approach is to use this to
-                store the characters moved when moving both the start and end of the range to the start of the document
-                body and subtracting the start offset from the end offset (the "move-negative-gazillion" method).
-                However, this is extremely slow when the document is large and the range is near the end of it. Clearly
-                doing the mirror image (i.e. moving the range boundaries to the end of the document) has the same
-                problem.
-
-                Another approach that works is to use moveStart() to move the start boundary of the range up to the end
-                boundary one character at a time and incrementing a counter with the value returned by the moveStart()
-                call. However, the check for whether the start boundary has reached the end boundary is expensive, so
-                this method is slow (although unlike "move-negative-gazillion" is largely unaffected by the location of
-                the range within the document).
-
-                The method below is a hybrid of the two methods above. It uses the fact that a string containing the
-                TextRange's 'text' property with each \r\n converted to a single \r character cannot be longer than the
-                text of the TextRange, so the start of the range is moved that length initially and then a character at
-                a time to make up for any trailing line breaks not contained in the 'text' property. This has good
-                performance in most situations compared to the previous two methods.
-                */
-                var tempRange = workingRange.duplicate();
-                var rangeLength = tempRange.text.replace(/\r\n/g, "\r").length;
-
-                offset = tempRange.moveStart("character", rangeLength);
-                while ( (comparison = tempRange.compareEndPoints("StartToEnd", tempRange)) == -1) {
-                    offset++;
-                    tempRange.moveStart("character", 1);
-                }
-            } else {
-                offset = workingRange.text.length;
-            }
-            boundaryPosition = new DomPosition(boundaryNode, offset);
-        } else {
-
-
-            // If the boundary immediately follows a character data node and this is the end boundary, we should favour
-            // a position within that, and likewise for a start boundary preceding a character data node
-            previousNode = (isCollapsed || !isStart) && workingNode.previousSibling;
-            nextNode = (isCollapsed || isStart) && workingNode.nextSibling;
-
-
-
-            if (nextNode && dom.isCharacterDataNode(nextNode)) {
-                boundaryPosition = new DomPosition(nextNode, 0);
-            } else if (previousNode && dom.isCharacterDataNode(previousNode)) {
-                boundaryPosition = new DomPosition(previousNode, previousNode.length);
-            } else {
-                boundaryPosition = new DomPosition(containerElement, dom.getNodeIndex(workingNode));
-            }
-        }
-
-        // Clean up
-        workingNode.parentNode.removeChild(workingNode);
-
-        return boundaryPosition;
-    }
-
-    // Returns a TextRange representing the boundary of a TextRange expressed as a node and an offset within that node.
-    // This function started out as an optimized version of code found in Tim Cameron Ryan's IERange
-    // (http://code.google.com/p/ierange/)
-    function createBoundaryTextRange(boundaryPosition, isStart) {
-        var boundaryNode, boundaryParent, boundaryOffset = boundaryPosition.offset;
-        var doc = dom.getDocument(boundaryPosition.node);
-        var workingNode, childNodes, workingRange = doc.body.createTextRange();
-        var nodeIsDataNode = dom.isCharacterDataNode(boundaryPosition.node);
-
-        if (nodeIsDataNode) {
-            boundaryNode = boundaryPosition.node;
-            boundaryParent = boundaryNode.parentNode;
-        } else {
-            childNodes = boundaryPosition.node.childNodes;
-            boundaryNode = (boundaryOffset < childNodes.length) ? childNodes[boundaryOffset] : null;
-            boundaryParent = boundaryPosition.node;
-        }
-
-        // Position the range immediately before the node containing the boundary
-        workingNode = doc.createElement("span");
-
-        // Making the working element non-empty element persuades IE to consider the TextRange boundary to be within the
-        // element rather than immediately before or after it, which is what we want
-        workingNode.innerHTML = "&#feff;";
-
-        // insertBefore is supposed to work like appendChild if the second parameter is null. However, a bug report
-        // for IERange suggests that it can crash the browser: http://code.google.com/p/ierange/issues/detail?id=12
-        if (boundaryNode) {
-            boundaryParent.insertBefore(workingNode, boundaryNode);
-        } else {
-            boundaryParent.appendChild(workingNode);
-        }
-
-        workingRange.moveToElementText(workingNode);
-        workingRange.collapse(!isStart);
-
-        // Clean up
-        boundaryParent.removeChild(workingNode);
-
-        // Move the working range to the text offset, if required
-        if (nodeIsDataNode) {
-            workingRange[isStart ? "moveStart" : "moveEnd"]("character", boundaryOffset);
-        }
-
-        return workingRange;
-    }
-
-    /*----------------------------------------------------------------------------------------------------------------*/
-
-    if (api.features.implementsDomRange && (!api.features.implementsTextRange || !api.config.preferTextRange)) {
-        // This is a wrapper around the browser's native DOM Range. It has two aims:
-        // - Provide workarounds for specific browser bugs
-        // - provide convenient extensions, which are inherited from Rangy's DomRange
-
-        (function() {
-            var rangeProto;
-            var rangeProperties = DomRange.rangeProperties;
-            var canSetRangeStartAfterEnd;
-
-            function updateRangeProperties(range) {
-                var i = rangeProperties.length, prop;
-                while (i--) {
-                    prop = rangeProperties[i];
-                    range[prop] = range.nativeRange[prop];
-                }
-            }
-
-            function updateNativeRange(range, startContainer, startOffset, endContainer,endOffset) {
-                var startMoved = (range.startContainer !== startContainer || range.startOffset != startOffset);
-                var endMoved = (range.endContainer !== endContainer || range.endOffset != endOffset);
-
-                // Always set both boundaries for the benefit of IE9 (see issue 35)
-                if (startMoved || endMoved) {
-                    range.setEnd(endContainer, endOffset);
-                    range.setStart(startContainer, startOffset);
-                }
-            }
-
-            function detach(range) {
-                range.nativeRange.detach();
-                range.detached = true;
-                var i = rangeProperties.length, prop;
-                while (i--) {
-                    prop = rangeProperties[i];
-                    range[prop] = null;
-                }
-            }
-
-            var createBeforeAfterNodeSetter;
-
-            WrappedRange = function(range) {
-                if (!range) {
-                    throw new Error("Range must be specified");
-                }
-                this.nativeRange = range;
-                updateRangeProperties(this);
-            };
-
-            DomRange.createPrototypeRange(WrappedRange, updateNativeRange, detach);
-
-            rangeProto = WrappedRange.prototype;
-
-            rangeProto.selectNode = function(node) {
-                this.nativeRange.selectNode(node);
-                updateRangeProperties(this);
-            };
-
-            rangeProto.deleteContents = function() {
-                this.nativeRange.deleteContents();
-                updateRangeProperties(this);
-            };
-
-            rangeProto.extractContents = function() {
-                var frag = this.nativeRange.extractContents();
-                updateRangeProperties(this);
-                return frag;
-            };
-
-            rangeProto.cloneContents = function() {
-                return this.nativeRange.cloneContents();
-            };
-
-            // TODO: Until I can find a way to programmatically trigger the Firefox bug (apparently long-standing, still
-            // present in 3.6.8) that throws "Index or size is negative or greater than the allowed amount" for
-            // insertNode in some circumstances, all browsers will have to use the Rangy's own implementation of
-            // insertNode, which works but is almost certainly slower than the native implementation.
-/*
-            rangeProto.insertNode = function(node) {
-                this.nativeRange.insertNode(node);
-                updateRangeProperties(this);
-            };
-*/
-
-            rangeProto.surroundContents = function(node) {
-                this.nativeRange.surroundContents(node);
-                updateRangeProperties(this);
-            };
-
-            rangeProto.collapse = function(isStart) {
-                this.nativeRange.collapse(isStart);
-                updateRangeProperties(this);
-            };
-
-            rangeProto.cloneRange = function() {
-                return new WrappedRange(this.nativeRange.cloneRange());
-            };
-
-            rangeProto.refresh = function() {
-                updateRangeProperties(this);
-            };
-
-            rangeProto.toString = function() {
-                return this.nativeRange.toString();
-            };
-
-            // Create test range and node for feature detection
-
-            var testTextNode = document.createTextNode("test");
-            dom.getBody(document).appendChild(testTextNode);
-            var range = document.createRange();
-
-            /*--------------------------------------------------------------------------------------------------------*/
-
-            // Test for Firefox 2 bug that prevents moving the start of a Range to a point after its current end and
-            // correct for it
-
-            range.setStart(testTextNode, 0);
-            range.setEnd(testTextNode, 0);
-
-            try {
-                range.setStart(testTextNode, 1);
-                canSetRangeStartAfterEnd = true;
-
-                rangeProto.setStart = function(node, offset) {
-                    this.nativeRange.setStart(node, offset);
-                    updateRangeProperties(this);
-                };
-
-                rangeProto.setEnd = function(node, offset) {
-                    this.nativeRange.setEnd(node, offset);
-                    updateRangeProperties(this);
-                };
-
-                createBeforeAfterNodeSetter = function(name) {
-                    return function(node) {
-                        this.nativeRange[name](node);
-                        updateRangeProperties(this);
-                    };
-                };
-
-            } catch(ex) {
-
-
-                canSetRangeStartAfterEnd = false;
-
-                rangeProto.setStart = function(node, offset) {
-                    try {
-                        this.nativeRange.setStart(node, offset);
-                    } catch (ex) {
-                        this.nativeRange.setEnd(node, offset);
-                        this.nativeRange.setStart(node, offset);
-                    }
-                    updateRangeProperties(this);
-                };
-
-                rangeProto.setEnd = function(node, offset) {
-                    try {
-                        this.nativeRange.setEnd(node, offset);
-                    } catch (ex) {
-                        this.nativeRange.setStart(node, offset);
-                        this.nativeRange.setEnd(node, offset);
-                    }
-                    updateRangeProperties(this);
-                };
-
-                createBeforeAfterNodeSetter = function(name, oppositeName) {
-                    return function(node) {
-                        try {
-                            this.nativeRange[name](node);
-                        } catch (ex) {
-                            this.nativeRange[oppositeName](node);
-                            this.nativeRange[name](node);
-                        }
-                        updateRangeProperties(this);
-                    };
-                };
-            }
-
-            rangeProto.setStartBefore = createBeforeAfterNodeSetter("setStartBefore", "setEndBefore");
-            rangeProto.setStartAfter = createBeforeAfterNodeSetter("setStartAfter", "setEndAfter");
-            rangeProto.setEndBefore = createBeforeAfterNodeSetter("setEndBefore", "setStartBefore");
-            rangeProto.setEndAfter = createBeforeAfterNodeSetter("setEndAfter", "setStartAfter");
-
-            /*--------------------------------------------------------------------------------------------------------*/
-
-            // Test for and correct Firefox 2 behaviour with selectNodeContents on text nodes: it collapses the range to
-            // the 0th character of the text node
-            range.selectNodeContents(testTextNode);
-            if (range.startContainer == testTextNode && range.endContainer == testTextNode &&
-                    range.startOffset == 0 && range.endOffset == testTextNode.length) {
-                rangeProto.selectNodeContents = function(node) {
-                    this.nativeRange.selectNodeContents(node);
-                    updateRangeProperties(this);
-                };
-            } else {
-                rangeProto.selectNodeContents = function(node) {
-                    this.setStart(node, 0);
-                    this.setEnd(node, DomRange.getEndOffset(node));
-                };
-            }
-
-            /*--------------------------------------------------------------------------------------------------------*/
-
-            // Test for WebKit bug that has the beahviour of compareBoundaryPoints round the wrong way for constants
-            // START_TO_END and END_TO_START: https://bugs.webkit.org/show_bug.cgi?id=20738
-
-            range.selectNodeContents(testTextNode);
-            range.setEnd(testTextNode, 3);
-
-            var range2 = document.createRange();
-            range2.selectNodeContents(testTextNode);
-            range2.setEnd(testTextNode, 4);
-            range2.setStart(testTextNode, 2);
-
-            if (range.compareBoundaryPoints(range.START_TO_END, range2) == -1 &
-                    range.compareBoundaryPoints(range.END_TO_START, range2) == 1) {
-                // This is the wrong way round, so correct for it
-
-
-                rangeProto.compareBoundaryPoints = function(type, range) {
-                    range = range.nativeRange || range;
-                    if (type == range.START_TO_END) {
-                        type = range.END_TO_START;
-                    } else if (type == range.END_TO_START) {
-                        type = range.START_TO_END;
-                    }
-                    return this.nativeRange.compareBoundaryPoints(type, range);
-                };
-            } else {
-                rangeProto.compareBoundaryPoints = function(type, range) {
-                    return this.nativeRange.compareBoundaryPoints(type, range.nativeRange || range);
-                };
-            }
-
-            /*--------------------------------------------------------------------------------------------------------*/
-
-            // Test for existence of createContextualFragment and delegate to it if it exists
-            if (api.util.isHostMethod(range, "createContextualFragment")) {
-                rangeProto.createContextualFragment = function(fragmentStr) {
-                    return this.nativeRange.createContextualFragment(fragmentStr);
-                };
-            }
-
-            /*--------------------------------------------------------------------------------------------------------*/
-
-            // Clean up
-            dom.getBody(document).removeChild(testTextNode);
-            range.detach();
-            range2.detach();
-        })();
-
-        api.createNativeRange = function(doc) {
-            doc = doc || document;
-            return doc.createRange();
-        };
-    } else if (api.features.implementsTextRange) {
-        // This is a wrapper around a TextRange, providing full DOM Range functionality using rangy's DomRange as a
-        // prototype
-
-        WrappedRange = function(textRange) {
-            this.textRange = textRange;
-            this.refresh();
-        };
-
-        WrappedRange.prototype = new DomRange(document);
-
-        WrappedRange.prototype.refresh = function() {
-            var start, end;
-
-            // TextRange's parentElement() method cannot be trusted. getTextRangeContainerElement() works around that.
-            var rangeContainerElement = getTextRangeContainerElement(this.textRange);
-
-            if (textRangeIsCollapsed(this.textRange)) {
-                end = start = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, true, true);
-            } else {
-
-                start = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, true, false);
-                end = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, false, false);
-            }
-
-            this.setStart(start.node, start.offset);
-            this.setEnd(end.node, end.offset);
-        };
-
-        DomRange.copyComparisonConstants(WrappedRange);
-
-        // Add WrappedRange as the Range property of the global object to allow expression like Range.END_TO_END to work
-        var globalObj = (function() { return this; })();
-        if (typeof globalObj.Range == "undefined") {
-            globalObj.Range = WrappedRange;
-        }
-
-        api.createNativeRange = function(doc) {
-            doc = doc || document;
-            return doc.body.createTextRange();
-        };
-    }
-
-    if (api.features.implementsTextRange) {
-        WrappedRange.rangeToTextRange = function(range) {
-            if (range.collapsed) {
-                var tr = createBoundaryTextRange(new DomPosition(range.startContainer, range.startOffset), true);
-
-
-
-                return tr;
-
-                //return createBoundaryTextRange(new DomPosition(range.startContainer, range.startOffset), true);
-            } else {
-                var startRange = createBoundaryTextRange(new DomPosition(range.startContainer, range.startOffset), true);
-                var endRange = createBoundaryTextRange(new DomPosition(range.endContainer, range.endOffset), false);
-                var textRange = dom.getDocument(range.startContainer).body.createTextRange();
-                textRange.setEndPoint("StartToStart", startRange);
-                textRange.setEndPoint("EndToEnd", endRange);
-                return textRange;
-            }
-        };
-    }
-
-    WrappedRange.prototype.getName = function() {
-        return "WrappedRange";
-    };
-
-    api.WrappedRange = WrappedRange;
-
-    api.createRange = function(doc) {
-        doc = doc || document;
-        return new WrappedRange(api.createNativeRange(doc));
-    };
-
-    api.createRangyRange = function(doc) {
-        doc = doc || document;
-        return new DomRange(doc);
-    };
-
-    api.createIframeRange = function(iframeEl) {
-        return api.createRange(dom.getIframeDocument(iframeEl));
-    };
-
-    api.createIframeRangyRange = function(iframeEl) {
-        return api.createRangyRange(dom.getIframeDocument(iframeEl));
-    };
-
-    api.addCreateMissingNativeApiListener(function(win) {
-        var doc = win.document;
-        if (typeof doc.createRange == "undefined") {
-            doc.createRange = function() {
-                return api.createRange(this);
-            };
-        }
-        doc = win = null;
-    });
-});rangy.createModule("WrappedSelection", function(api, module) {
-    // This will create a selection object wrapper that follows the Selection object found in the WHATWG draft DOM Range
-    // spec (http://html5.org/specs/dom-range.html)
-
-    api.requireModules( ["DomUtil", "DomRange", "WrappedRange"] );
-
-    api.config.checkSelectionRanges = true;
-
-    var BOOLEAN = "boolean",
-        windowPropertyName = "_rangySelection",
-        dom = api.dom,
-        util = api.util,
-        DomRange = api.DomRange,
-        WrappedRange = api.WrappedRange,
-        DOMException = api.DOMException,
-        DomPosition = dom.DomPosition,
-        getSelection,
-        selectionIsCollapsed,
-        CONTROL = "Control";
-
-
-
-    function getWinSelection(winParam) {
-        return (winParam || window).getSelection();
-    }
-
-    function getDocSelection(winParam) {
-        return (winParam || window).document.selection;
-    }
-
-    // Test for the Range/TextRange and Selection features required
-    // Test for ability to retrieve selection
-    var implementsWinGetSelection = api.util.isHostMethod(window, "getSelection"),
-        implementsDocSelection = api.util.isHostObject(document, "selection");
-
-    var useDocumentSelection = implementsDocSelection && (!implementsWinGetSelection || api.config.preferTextRange);
-
-    if (useDocumentSelection) {
-        getSelection = getDocSelection;
-        api.isSelectionValid = function(winParam) {
-            var doc = (winParam || window).document, nativeSel = doc.selection;
-
-            // Check whether the selection TextRange is actually contained within the correct document
-            return (nativeSel.type != "None" || dom.getDocument(nativeSel.createRange().parentElement()) == doc);
-        };
-    } else if (implementsWinGetSelection) {
-        getSelection = getWinSelection;
-        api.isSelectionValid = function() {
-            return true;
-        };
-    } else {
-        module.fail("Neither document.selection or window.getSelection() detected.");
-    }
-
-    api.getNativeSelection = getSelection;
-
-    var testSelection = getSelection();
-    var testRange = api.createNativeRange(document);
-    var body = dom.getBody(document);
-
-    // Obtaining a range from a selection
-    var selectionHasAnchorAndFocus = util.areHostObjects(testSelection, ["anchorNode", "focusNode"] &&
-                                     util.areHostProperties(testSelection, ["anchorOffset", "focusOffset"]));
-    api.features.selectionHasAnchorAndFocus = selectionHasAnchorAndFocus;
-
-    // Test for existence of native selection extend() method
-    var selectionHasExtend = util.isHostMethod(testSelection, "extend");
-    api.features.selectionHasExtend = selectionHasExtend;
-
-    // Test if rangeCount exists
-    var selectionHasRangeCount = (typeof testSelection.rangeCount == "number");
-    api.features.selectionHasRangeCount = selectionHasRangeCount;
-
-    var selectionSupportsMultipleRanges = false;
-    var collapsedNonEditableSelectionsSupported = true;
-
-    if (util.areHostMethods(testSelection, ["addRange", "getRangeAt", "removeAllRanges"]) &&
-            typeof testSelection.rangeCount == "number" && api.features.implementsDomRange) {
-
-        (function() {
-            var iframe = document.createElement("iframe");
-            body.appendChild(iframe);
-
-            var iframeDoc = dom.getIframeDocument(iframe);
-            iframeDoc.open();
-            iframeDoc.write("12");
-            iframeDoc.close();
-
-            var sel = dom.getIframeWindow(iframe).getSelection();
-            var docEl = iframeDoc.documentElement;
-            var iframeBody = docEl.lastChild, textNode = iframeBody.firstChild;
-
-            // Test whether the native selection will allow a collapsed selection within a non-editable element
-            var r1 = iframeDoc.createRange();
-            r1.setStart(textNode, 1);
-            r1.collapse(true);
-            sel.addRange(r1);
-            collapsedNonEditableSelectionsSupported = (sel.rangeCount == 1);
-            sel.removeAllRanges();
-
-            // Test whether the native selection is capable of supporting multiple ranges
-            var r2 = r1.cloneRange();
-            r1.setStart(textNode, 0);
-            r2.setEnd(textNode, 2);
-            sel.addRange(r1);
-            sel.addRange(r2);
-
-            selectionSupportsMultipleRanges = (sel.rangeCount == 2);
-
-            // Clean up
-            r1.detach();
-            r2.detach();
-
-            body.removeChild(iframe);
-        })();
-    }
-
-    api.features.selectionSupportsMultipleRanges = selectionSupportsMultipleRanges;
-    api.features.collapsedNonEditableSelectionsSupported = collapsedNonEditableSelectionsSupported;
-
-    // ControlRanges
-    var implementsControlRange = false, testControlRange;
-
-    if (body && util.isHostMethod(body, "createControlRange")) {
-        testControlRange = body.createControlRange();
-        if (util.areHostProperties(testControlRange, ["item", "add"])) {
-            implementsControlRange = true;
-        }
-    }
-    api.features.implementsControlRange = implementsControlRange;
-
-    // Selection collapsedness
-    if (selectionHasAnchorAndFocus) {
-        selectionIsCollapsed = function(sel) {
-            return sel.anchorNode === sel.focusNode && sel.anchorOffset === sel.focusOffset;
-        };
-    } else {
-        selectionIsCollapsed = function(sel) {
-            return sel.rangeCount ? sel.getRangeAt(sel.rangeCount - 1).collapsed : false;
-        };
-    }
-
-    function updateAnchorAndFocusFromRange(sel, range, backwards) {
-        var anchorPrefix = backwards ? "end" : "start", focusPrefix = backwards ? "start" : "end";
-        sel.anchorNode = range[anchorPrefix + "Container"];
-        sel.anchorOffset = range[anchorPrefix + "Offset"];
-        sel.focusNode = range[focusPrefix + "Container"];
-        sel.focusOffset = range[focusPrefix + "Offset"];
-    }
-
-    function updateAnchorAndFocusFromNativeSelection(sel) {
-        var nativeSel = sel.nativeSelection;
-        sel.anchorNode = nativeSel.anchorNode;
-        sel.anchorOffset = nativeSel.anchorOffset;
-        sel.focusNode = nativeSel.focusNode;
-        sel.focusOffset = nativeSel.focusOffset;
-    }
-
-    function updateEmptySelection(sel) {
-        sel.anchorNode = sel.focusNode = null;
-        sel.anchorOffset = sel.focusOffset = 0;
-        sel.rangeCount = 0;
-        sel.isCollapsed = true;
-        sel._ranges.length = 0;
-    }
-
-    function getNativeRange(range) {
-        var nativeRange;
-        if (range instanceof DomRange) {
-            nativeRange = range._selectionNativeRange;
-            if (!nativeRange) {
-                nativeRange = api.createNativeRange(dom.getDocument(range.startContainer));
-                nativeRange.setEnd(range.endContainer, range.endOffset);
-                nativeRange.setStart(range.startContainer, range.startOffset);
-                range._selectionNativeRange = nativeRange;
-                range.attachListener("detach", function() {
-
-                    this._selectionNativeRange = null;
-                });
-            }
-        } else if (range instanceof WrappedRange) {
-            nativeRange = range.nativeRange;
-        } else if (api.features.implementsDomRange && (range instanceof dom.getWindow(range.startContainer).Range)) {
-            nativeRange = range;
-        }
-        return nativeRange;
-    }
-
-    function rangeContainsSingleElement(rangeNodes) {
-        if (!rangeNodes.length || rangeNodes[0].nodeType != 1) {
-            return false;
-        }
-        for (var i = 1, len = rangeNodes.length; i < len; ++i) {
-            if (!dom.isAncestorOf(rangeNodes[0], rangeNodes[i])) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    function getSingleElementFromRange(range) {
-        var nodes = range.getNodes();
-        if (!rangeContainsSingleElement(nodes)) {
-            throw new Error("getSingleElementFromRange: range " + range.inspect() + " did not consist of a single element");
-        }
-        return nodes[0];
-    }
-
-    function isTextRange(range) {
-        return !!range && typeof range.text != "undefined";
-    }
-
-    function updateFromTextRange(sel, range) {
-        // Create a Range from the selected TextRange
-        var wrappedRange = new WrappedRange(range);
-        sel._ranges = [wrappedRange];
-
-        updateAnchorAndFocusFromRange(sel, wrappedRange, false);
-        sel.rangeCount = 1;
-        sel.isCollapsed = wrappedRange.collapsed;
-    }
-
-    function updateControlSelection(sel) {
-        // Update the wrapped selection based on what's now in the native selection
-        sel._ranges.length = 0;
-        if (sel.docSelection.type == "None") {
-            updateEmptySelection(sel);
-        } else {
-            var controlRange = sel.docSelection.createRange();
-            if (isTextRange(controlRange)) {
-                // This case (where the selection type is "Control" and calling createRange() on the selection returns
-                // a TextRange) can happen in IE 9. It happens, for example, when all elements in the selected
-                // ControlRange have been removed from the ControlRange and removed from the document.
-                updateFromTextRange(sel, controlRange);
-            } else {
-                sel.rangeCount = controlRange.length;
-                var range, doc = dom.getDocument(controlRange.item(0));
-                for (var i = 0; i < sel.rangeCount; ++i) {
-                    range = api.createRange(doc);
-                    range.selectNode(controlRange.item(i));
-                    sel._ranges.push(range);
-                }
-                sel.isCollapsed = sel.rangeCount == 1 && sel._ranges[0].collapsed;
-                updateAnchorAndFocusFromRange(sel, sel._ranges[sel.rangeCount - 1], false);
-            }
-        }
-    }
-
-    function addRangeToControlSelection(sel, range) {
-        var controlRange = sel.docSelection.createRange();
-        var rangeElement = getSingleElementFromRange(range);
-
-        // Create a new ControlRange containing all the elements in the selected ControlRange plus the element
-        // contained by the supplied range
-        var doc = dom.getDocument(controlRange.item(0));
-        var newControlRange = dom.getBody(doc).createControlRange();
-        for (var i = 0, len = controlRange.length; i < len; ++i) {
-            newControlRange.add(controlRange.item(i));
-        }
-        try {
-            newControlRange.add(rangeElement);
-        } catch (ex) {
-            throw new Error("addRange(): Element within the specified Range could not be added to control selection (does it have layout?)");
-        }
-        newControlRange.select();
-
-        // Update the wrapped selection based on what's now in the native selection
-        updateControlSelection(sel);
-    }
-
-    var getSelectionRangeAt;
-
-    if (util.isHostMethod(testSelection,  "getRangeAt")) {
-        getSelectionRangeAt = function(sel, index) {
-            try {
-                return sel.getRangeAt(index);
-            } catch(ex) {
-                return null;
-            }
-        };
-    } else if (selectionHasAnchorAndFocus) {
-        getSelectionRangeAt = function(sel) {
-            var doc = dom.getDocument(sel.anchorNode);
-            var range = api.createRange(doc);
-            range.setStart(sel.anchorNode, sel.anchorOffset);
-            range.setEnd(sel.focusNode, sel.focusOffset);
-
-            // Handle the case when the selection was selected backwards (from the end to the start in the
-            // document)
-            if (range.collapsed !== this.isCollapsed) {
-                range.setStart(sel.focusNode, sel.focusOffset);
-                range.setEnd(sel.anchorNode, sel.anchorOffset);
-            }
-
-            return range;
-        };
-    }
-
-    /**
-     * @constructor
-     */
-    function WrappedSelection(selection, docSelection, win) {
-        this.nativeSelection = selection;
-        this.docSelection = docSelection;
-        this._ranges = [];
-        this.win = win;
-        this.refresh();
-    }
-
-    api.getSelection = function(win) {
-        win = win || window;
-        var sel = win[windowPropertyName];
-        var nativeSel = getSelection(win), docSel = implementsDocSelection ? getDocSelection(win) : null;
-        if (sel) {
-            sel.nativeSelection = nativeSel;
-            sel.docSelection = docSel;
-            sel.refresh(win);
-        } else {
-            sel = new WrappedSelection(nativeSel, docSel, win);
-            win[windowPropertyName] = sel;
-        }
-        return sel;
-    };
-
-    api.getIframeSelection = function(iframeEl) {
-        return api.getSelection(dom.getIframeWindow(iframeEl));
-    };
-
-    var selProto = WrappedSelection.prototype;
-
-    function createControlSelection(sel, ranges) {
-        // Ensure that the selection becomes of type "Control"
-        var doc = dom.getDocument(ranges[0].startContainer);
-        var controlRange = dom.getBody(doc).createControlRange();
-        for (var i = 0, el; i < rangeCount; ++i) {
-            el = getSingleElementFromRange(ranges[i]);
-            try {
-                controlRange.add(el);
-            } catch (ex) {
-                throw new Error("setRanges(): Element within the one of the specified Ranges could not be added to control selection (does it have layout?)");
-            }
-        }
-        controlRange.select();
-
-        // Update the wrapped selection based on what's now in the native selection
-        updateControlSelection(sel);
-    }
-
-    // Selecting a range
-    if (!useDocumentSelection && selectionHasAnchorAndFocus && util.areHostMethods(testSelection, ["removeAllRanges", "addRange"])) {
-        selProto.removeAllRanges = function() {
-            this.nativeSelection.removeAllRanges();
-            updateEmptySelection(this);
-        };
-
-        var addRangeBackwards = function(sel, range) {
-            var doc = DomRange.getRangeDocument(range);
-            var endRange = api.createRange(doc);
-            endRange.collapseToPoint(range.endContainer, range.endOffset);
-            sel.nativeSelection.addRange(getNativeRange(endRange));
-            sel.nativeSelection.extend(range.startContainer, range.startOffset);
-            sel.refresh();
-        };
-
-        if (selectionHasRangeCount) {
-            selProto.addRange = function(range, backwards) {
-                if (implementsControlRange && implementsDocSelection && this.docSelection.type == CONTROL) {
-                    addRangeToControlSelection(this, range);
-                } else {
-                    if (backwards && selectionHasExtend) {
-                        addRangeBackwards(this, range);
-                    } else {
-                        var previousRangeCount;
-                        if (selectionSupportsMultipleRanges) {
-                            previousRangeCount = this.rangeCount;
-                        } else {
-                            this.removeAllRanges();
-                            previousRangeCount = 0;
-                        }
-                        this.nativeSelection.addRange(getNativeRange(range));
-
-                        // Check whether adding the range was successful
-                        this.rangeCount = this.nativeSelection.rangeCount;
-
-                        if (this.rangeCount == previousRangeCount + 1) {
-                            // The range was added successfully
-
-                            // Check whether the range that we added to the selection is reflected in the last range extracted from
-                            // the selection
-                            if (api.config.checkSelectionRanges) {
-                                var nativeRange = getSelectionRangeAt(this.nativeSelection, this.rangeCount - 1);
-                                if (nativeRange && !DomRange.rangesEqual(nativeRange, range)) {
-                                    // Happens in WebKit with, for example, a selection placed at the start of a text node
-                                    range = new WrappedRange(nativeRange);
-                                }
-                            }
-                            this._ranges[this.rangeCount - 1] = range;
-                            updateAnchorAndFocusFromRange(this, range, selectionIsBackwards(this.nativeSelection));
-                            this.isCollapsed = selectionIsCollapsed(this);
-                        } else {
-                            // The range was not added successfully. The simplest thing is to refresh
-                            this.refresh();
-                        }
-                    }
-                }
-            };
-        } else {
-            selProto.addRange = function(range, backwards) {
-                if (backwards && selectionHasExtend) {
-                    addRangeBackwards(this, range);
-                } else {
-                    this.nativeSelection.addRange(getNativeRange(range));
-                    this.refresh();
-                }
-            };
-        }
-
-        selProto.setRanges = function(ranges) {
-            if (implementsControlRange && ranges.length > 1) {
-                createControlSelection(this, ranges);
-            } else {
-                this.removeAllRanges();
-                for (var i = 0, len = ranges.length; i < len; ++i) {
-                    this.addRange(ranges[i]);
-                }
-            }
-        };
-    } else if (util.isHostMethod(testSelection, "empty") && util.isHostMethod(testRange, "select") &&
-               implementsControlRange && useDocumentSelection) {
-
-        selProto.removeAllRanges = function() {
-            // Added try/catch as fix for issue #21
-            try {
-                this.docSelection.empty();
-
-                // Check for empty() not working (issue #24)
-                if (this.docSelection.type != "None") {
-                    // Work around failure to empty a control selection by instead selecting a TextRange and then
-                    // calling empty()
-                    var doc;
-                    if (this.anchorNode) {
-                        doc = dom.getDocument(this.anchorNode);
-                    } else if (this.docSelection.type == CONTROL) {
-                        var controlRange = this.docSelection.createRange();
-                        if (controlRange.length) {
-                            doc = dom.getDocument(controlRange.item(0)).body.createTextRange();
-                        }
-                    }
-                    if (doc) {
-                        var textRange = doc.body.createTextRange();
-                        textRange.select();
-                        this.docSelection.empty();
-                    }
-                }
-            } catch(ex) {}
-            updateEmptySelection(this);
-        };
-
-        selProto.addRange = function(range) {
-            if (this.docSelection.type == CONTROL) {
-                addRangeToControlSelection(this, range);
-            } else {
-                WrappedRange.rangeToTextRange(range).select();
-                this._ranges[0] = range;
-                this.rangeCount = 1;
-                this.isCollapsed = this._ranges[0].collapsed;
-                updateAnchorAndFocusFromRange(this, range, false);
-            }
-        };
-
-        selProto.setRanges = function(ranges) {
-            this.removeAllRanges();
-            var rangeCount = ranges.length;
-            if (rangeCount > 1) {
-                createControlSelection(this, ranges);
-            } else if (rangeCount) {
-                this.addRange(ranges[0]);
-            }
-        };
-    } else {
-        module.fail("No means of selecting a Range or TextRange was found");
-        return false;
-    }
-
-    selProto.getRangeAt = function(index) {
-        if (index < 0 || index >= this.rangeCount) {
-            throw new DOMException("INDEX_SIZE_ERR");
-        } else {
-            return this._ranges[index];
-        }
-    };
-
-    var refreshSelection;
-
-    if (useDocumentSelection) {
-        refreshSelection = function(sel) {
-            var range;
-            if (api.isSelectionValid(sel.win)) {
-                range = sel.docSelection.createRange();
-            } else {
-                range = dom.getBody(sel.win.document).createTextRange();
-                range.collapse(true);
-            }
-
-
-            if (sel.docSelection.type == CONTROL) {
-                updateControlSelection(sel);
-            } else if (isTextRange(range)) {
-                updateFromTextRange(sel, range);
-            } else {
-                updateEmptySelection(sel);
-            }
-        };
-    } else if (util.isHostMethod(testSelection, "getRangeAt") && typeof testSelection.rangeCount == "number") {
-        refreshSelection = function(sel) {
-            if (implementsControlRange && implementsDocSelection && sel.docSelection.type == CONTROL) {
-                updateControlSelection(sel);
-            } else {
-                sel._ranges.length = sel.rangeCount = sel.nativeSelection.rangeCount;
-                if (sel.rangeCount) {
-                    for (var i = 0, len = sel.rangeCount; i < len; ++i) {
-                        sel._ranges[i] = new api.WrappedRange(sel.nativeSelection.getRangeAt(i));
-                    }
-                    updateAnchorAndFocusFromRange(sel, sel._ranges[sel.rangeCount - 1], selectionIsBackwards(sel.nativeSelection));
-                    sel.isCollapsed = selectionIsCollapsed(sel);
-                } else {
-                    updateEmptySelection(sel);
-                }
-            }
-        };
-    } else if (selectionHasAnchorAndFocus && typeof testSelection.isCollapsed == BOOLEAN && typeof testRange.collapsed == BOOLEAN && api.features.implementsDomRange) {
-        refreshSelection = function(sel) {
-            var range, nativeSel = sel.nativeSelection;
-            if (nativeSel.anchorNode) {
-                range = getSelectionRangeAt(nativeSel, 0);
-                sel._ranges = [range];
-                sel.rangeCount = 1;
-                updateAnchorAndFocusFromNativeSelection(sel);
-                sel.isCollapsed = selectionIsCollapsed(sel);
-            } else {
-                updateEmptySelection(sel);
-            }
-        };
-    } else {
-        module.fail("No means of obtaining a Range or TextRange from the user's selection was found");
-        return false;
-    }
-
-    selProto.refresh = function(checkForChanges) {
-        var oldRanges = checkForChanges ? this._ranges.slice(0) : null;
-        refreshSelection(this);
-        if (checkForChanges) {
-            var i = oldRanges.length;
-            if (i != this._ranges.length) {
-                return false;
-            }
-            while (i--) {
-                if (!DomRange.rangesEqual(oldRanges[i], this._ranges[i])) {
-                    return false;
-                }
-            }
-            return true;
-        }
-    };
-
-    // Removal of a single range
-    var removeRangeManually = function(sel, range) {
-        var ranges = sel.getAllRanges(), removed = false;
-        sel.removeAllRanges();
-        for (var i = 0, len = ranges.length; i < len; ++i) {
-            if (removed || range !== ranges[i]) {
-                sel.addRange(ranges[i]);
-            } else {
-                // According to the draft WHATWG Range spec, the same range may be added to the selection multiple
-                // times. removeRange should only remove the first instance, so the following ensures only the first
-                // instance is removed
-                removed = true;
-            }
-        }
-        if (!sel.rangeCount) {
-            updateEmptySelection(sel);
-        }
-    };
-
-    if (implementsControlRange) {
-        selProto.removeRange = function(range) {
-            if (this.docSelection.type == CONTROL) {
-                var controlRange = this.docSelection.createRange();
-                var rangeElement = getSingleElementFromRange(range);
-
-                // Create a new ControlRange containing all the elements in the selected ControlRange minus the
-                // element contained by the supplied range
-                var doc = dom.getDocument(controlRange.item(0));
-                var newControlRange = dom.getBody(doc).createControlRange();
-                var el, removed = false;
-                for (var i = 0, len = controlRange.length; i < len; ++i) {
-                    el = controlRange.item(i);
-                    if (el !== rangeElement || removed) {
-                        newControlRange.add(controlRange.item(i));
-                    } else {
-                        removed = true;
-                    }
-                }
-                newControlRange.select();
-
-                // Update the wrapped selection based on what's now in the native selection
-                updateControlSelection(this);
-            } else {
-                removeRangeManually(this, range);
-            }
-        };
-    } else {
-        selProto.removeRange = function(range) {
-            removeRangeManually(this, range);
-        };
-    }
-
-    // Detecting if a selection is backwards
-    var selectionIsBackwards;
-    if (!useDocumentSelection && selectionHasAnchorAndFocus && api.features.implementsDomRange) {
-        selectionIsBackwards = function(sel) {
-            var backwards = false;
-            if (sel.anchorNode) {
-                backwards = (dom.comparePoints(sel.anchorNode, sel.anchorOffset, sel.focusNode, sel.focusOffset) == 1);
-            }
-            return backwards;
-        };
-
-        selProto.isBackwards = function() {
-            return selectionIsBackwards(this);
-        };
-    } else {
-        selectionIsBackwards = selProto.isBackwards = function() {
-            return false;
-        };
-    }
-
-    // Selection text
-    // This is conformant to the new WHATWG DOM Range draft spec but differs from WebKit and Mozilla's implementation
-    selProto.toString = function() {
-
-        var rangeTexts = [];
-        for (var i = 0, len = this.rangeCount; i < len; ++i) {
-            rangeTexts[i] = "" + this._ranges[i];
-        }
-        return rangeTexts.join("");
-    };
-
-    function assertNodeInSameDocument(sel, node) {
-        if (sel.anchorNode && (dom.getDocument(sel.anchorNode) !== dom.getDocument(node))) {
-            throw new DOMException("WRONG_DOCUMENT_ERR");
-        }
-    }
-
-    // No current browsers conform fully to the HTML 5 draft spec for this method, so Rangy's own method is always used
-    selProto.collapse = function(node, offset) {
-        assertNodeInSameDocument(this, node);
-        var range = api.createRange(dom.getDocument(node));
-        range.collapseToPoint(node, offset);
-        this.removeAllRanges();
-        this.addRange(range);
-        this.isCollapsed = true;
-    };
-
-    selProto.collapseToStart = function() {
-        if (this.rangeCount) {
-            var range = this._ranges[0];
-            this.collapse(range.startContainer, range.startOffset);
-        } else {
-            throw new DOMException("INVALID_STATE_ERR");
-        }
-    };
-
-    selProto.collapseToEnd = function() {
-        if (this.rangeCount) {
-            var range = this._ranges[this.rangeCount - 1];
-            this.collapse(range.endContainer, range.endOffset);
-        } else {
-            throw new DOMException("INVALID_STATE_ERR");
-        }
-    };
-
-    // The HTML 5 spec is very specific on how selectAllChildren should be implemented so the native implementation is
-    // never used by Rangy.
-    selProto.selectAllChildren = function(node) {
-        assertNodeInSameDocument(this, node);
-        var range = api.createRange(dom.getDocument(node));
-        range.selectNodeContents(node);
-        this.removeAllRanges();
-        this.addRange(range);
-    };
-
-    selProto.deleteFromDocument = function() {
-        // Sepcial behaviour required for Control selections
-        if (implementsControlRange && implementsDocSelection && this.docSelection.type == CONTROL) {
-            var controlRange = this.docSelection.createRange();
-            var element;
-            while (controlRange.length) {
-                element = controlRange.item(0);
-                controlRange.remove(element);
-                element.parentNode.removeChild(element);
-            }
-            this.refresh();
-        } else if (this.rangeCount) {
-            var ranges = this.getAllRanges();
-            this.removeAllRanges();
-            for (var i = 0, len = ranges.length; i < len; ++i) {
-                ranges[i].deleteContents();
-            }
-            // The HTML5 spec says nothing about what the selection should contain after calling deleteContents on each
-            // range. Firefox moves the selection to where the final selected range was, so we emulate that
-            this.addRange(ranges[len - 1]);
-        }
-    };
-
-    // The following are non-standard extensions
-    selProto.getAllRanges = function() {
-        return this._ranges.slice(0);
-    };
-
-    selProto.setSingleRange = function(range) {
-        this.setRanges( [range] );
-    };
-
-    selProto.containsNode = function(node, allowPartial) {
-        for (var i = 0, len = this._ranges.length; i < len; ++i) {
-            if (this._ranges[i].containsNode(node, allowPartial)) {
-                return true;
-            }
-        }
-        return false;
-    };
-
-    selProto.toHtml = function() {
-        var html = "";
-        if (this.rangeCount) {
-            var container = DomRange.getRangeDocument(this._ranges[0]).createElement("div");
-            for (var i = 0, len = this._ranges.length; i < len; ++i) {
-                container.appendChild(this._ranges[i].cloneContents());
-            }
-            html = container.innerHTML;
-        }
-        return html;
-    };
-
-    function inspect(sel) {
-        var rangeInspects = [];
-        var anchor = new DomPosition(sel.anchorNode, sel.anchorOffset);
-        var focus = new DomPosition(sel.focusNode, sel.focusOffset);
-        var name = (typeof sel.getName == "function") ? sel.getName() : "Selection";
-
-        if (typeof sel.rangeCount != "undefined") {
-            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
-                rangeInspects[i] = DomRange.inspect(sel.getRangeAt(i));
-            }
-        }
-        return "[" + name + "(Ranges: " + rangeInspects.join(", ") +
-                ")(anchor: " + anchor.inspect() + ", focus: " + focus.inspect() + "]";
-
-    }
-
-    selProto.getName = function() {
-        return "WrappedSelection";
-    };
-
-    selProto.inspect = function() {
-        return inspect(this);
-    };
-
-    selProto.detach = function() {
-        this.win[windowPropertyName] = null;
-        this.win = this.anchorNode = this.focusNode = null;
-    };
-
-    WrappedSelection.inspect = inspect;
-
-    api.Selection = WrappedSelection;
-
-    api.selectionPrototype = selProto;
-
-    api.addCreateMissingNativeApiListener(function(win) {
-        if (typeof win.getSelection == "undefined") {
-            win.getSelection = function() {
-                return api.getSelection(this);
-            };
-        }
-        win = null;
-    });
-});
-/*
-	Base.js, version 1.1a
-	Copyright 2006-2010, Dean Edwards
-	License: http://www.opensource.org/licenses/mit-license.php
-*/
-
-var Base = function() {
-	// dummy
-};
-
-Base.extend = function(_instance, _static) { // subclass
-	var extend = Base.prototype.extend;
-	
-	// build the prototype
-	Base._prototyping = true;
-	var proto = new this;
-	extend.call(proto, _instance);
-  proto.base = function() {
-    // call this method from any other method to invoke that method's ancestor
-  };
-	delete Base._prototyping;
-	
-	// create the wrapper for the constructor function
-	//var constructor = proto.constructor.valueOf(); //-dean
-	var constructor = proto.constructor;
-	var klass = proto.constructor = function() {
-		if (!Base._prototyping) {
-			if (this._constructing || this.constructor == klass) { // instantiation
-				this._constructing = true;
-				constructor.apply(this, arguments);
-				delete this._constructing;
-			} else if (arguments[0] != null) { // casting
-				return (arguments[0].extend || extend).call(arguments[0], proto);
-			}
-		}
-	};
-	
-	// build the class interface
-	klass.ancestor = this;
-	klass.extend = this.extend;
-	klass.forEach = this.forEach;
-	klass.implement = this.implement;
-	klass.prototype = proto;
-	klass.toString = this.toString;
-	klass.valueOf = function(type) {
-		//return (type == "object") ? klass : constructor; //-dean
-		return (type == "object") ? klass : constructor.valueOf();
-	};
-	extend.call(klass, _static);
-	// class initialisation
-	if (typeof klass.init == "function") klass.init();
-	return klass;
-};
-
-Base.prototype = {	
-	extend: function(source, value) {
-		if (arguments.length > 1) { // extending with a name/value pair
-			var ancestor = this[source];
-			if (ancestor && (typeof value == "function") && // overriding a method?
-				// the valueOf() comparison is to avoid circular references
-				(!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) &&
-				/\bbase\b/.test(value)) {
-				// get the underlying method
-				var method = value.valueOf();
-				// override
-				value = function() {
-					var previous = this.base || Base.prototype.base;
-					this.base = ancestor;
-					var returnValue = method.apply(this, arguments);
-					this.base = previous;
-					return returnValue;
-				};
-				// point to the underlying method
-				value.valueOf = function(type) {
-					return (type == "object") ? value : method;
-				};
-				value.toString = Base.toString;
-			}
-			this[source] = value;
-		} else if (source) { // extending with an object literal
-			var extend = Base.prototype.extend;
-			// if this object has a customised extend method then use it
-			if (!Base._prototyping && typeof this != "function") {
-				extend = this.extend || extend;
-			}
-			var proto = {toSource: null};
-			// do the "toString" and other methods manually
-			var hidden = ["constructor", "toString", "valueOf"];
-			// if we are prototyping then include the constructor
-			var i = Base._prototyping ? 0 : 1;
-			while (key = hidden[i++]) {
-				if (source[key] != proto[key]) {
-					extend.call(this, key, source[key]);
-
-				}
-			}
-			// copy each of the source object's properties to this object
-			for (var key in source) {
-				if (!proto[key]) extend.call(this, key, source[key]);
-			}
-		}
-		return this;
-	}
-};
-
-// initialise
-Base = Base.extend({
-	constructor: function() {
-		this.extend(arguments[0]);
-	}
-}, {
-	ancestor: Object,
-	version: "1.1",
-	
-	forEach: function(object, block, context) {
-		for (var key in object) {
-			if (this.prototype[key] === undefined) {
-				block.call(context, object[key], key, object);
-			}
-		}
-	},
-		
-	implement: function() {
-		for (var i = 0; i < arguments.length; i++) {
-			if (typeof arguments[i] == "function") {
-				// if it's a function, call it
-				arguments[i](this.prototype);
-			} else {
-				// add the interface using the extend method
-				this.prototype.extend(arguments[i]);
-			}
-		}
-		return this;
-	},
-	
-	toString: function() {
-		return String(this.valueOf());
-	}
-});/**
- * Detect browser support for specific features
- */
-wysihtml5.browser = (function() {
-  var userAgent   = navigator.userAgent,
-      testElement = document.createElement("div"),
-      // Browser sniffing is unfortunately needed since some behaviors are impossible to feature detect
-      isIE        = userAgent.indexOf("MSIE")         !== -1 && userAgent.indexOf("Opera") === -1,
-      isGecko     = userAgent.indexOf("Gecko")        !== -1 && userAgent.indexOf("KHTML") === -1,
-      isWebKit    = userAgent.indexOf("AppleWebKit/") !== -1,
-      isChrome    = userAgent.indexOf("Chrome/")      !== -1,
-      isOpera     = userAgent.indexOf("Opera/")       !== -1;
-  
-  function iosVersion(userAgent) {
-    return ((/ipad|iphone|ipod/.test(userAgent) && userAgent.match(/ os (\d+).+? like mac os x/)) || [, 0])[1];
-  }
-  
-  return {
-    // Static variable needed, publicly accessible, to be able override it in unit tests
-    USER_AGENT: userAgent,
-    
-    /**
-     * Exclude browsers that are not capable of displaying and handling
-     * contentEditable as desired:
-     *    - iPhone, iPad (tested iOS 4.2.2) and Android (tested 2.2) refuse to make contentEditables focusable
-     *    - IE < 8 create invalid markup and crash randomly from time to time
-     *
-     * @return {Boolean}
-     */
-    supported: function() {
-      var userAgent                   = this.USER_AGENT.toLowerCase(),
-          // Essential for making html elements editable
-          hasContentEditableSupport   = "contentEditable" in testElement,
-          // Following methods are needed in order to interact with the contentEditable area
-          hasEditingApiSupport        = document.execCommand && document.queryCommandSupported && document.queryCommandState,
-          // document selector apis are only supported by IE 8+, Safari 4+, Chrome and Firefox 3.5+
-          hasQuerySelectorSupport     = document.querySelector && document.querySelectorAll,
-          // contentEditable is unusable in mobile browsers (tested iOS 4.2.2, Android 2.2, Opera Mobile, WebOS 3.05)
-          isIncompatibleMobileBrowser = (this.isIos() && iosVersion(userAgent) < 5) || userAgent.indexOf("opera mobi") !== -1 || userAgent.indexOf("hpwos/") !== -1;
-      
-      return hasContentEditableSupport
-        && hasEditingApiSupport
-        && hasQuerySelectorSupport
-        && !isIncompatibleMobileBrowser;
-    },
-    
-    isTouchDevice: function() {
-      return this.supportsEvent("touchmove");
-    },
-    
-    isIos: function() {
-      var userAgent = this.USER_AGENT.toLowerCase();
-      return userAgent.indexOf("webkit") !== -1 && userAgent.indexOf("mobile") !== -1;
-    },
-    
-    /**
-     * Whether the browser supports sandboxed iframes
-     * Currently only IE 6+ offers such feature