Browse Source

建立实体类、数据相关服务类及其他工具类

Yumin 5 years ago
parent
commit
ba39126a37
78 changed files with 15781 additions and 48 deletions
  1. 27 1
      pom.xml
  2. 2 2
      src/main/java/cn/minbb/iot/config/MqttSenderConfig.java
  3. 101 0
      src/main/java/cn/minbb/iot/config/WebSecurityConfig.java
  4. 3 2
      src/main/java/cn/minbb/iot/controller/rest/IoTController.java
  5. 3 3
      src/main/java/cn/minbb/iot/controller/rest/UserController.java
  6. 22 0
      src/main/java/cn/minbb/iot/controller/web/MainController.java
  7. 1 1
      src/main/java/cn/minbb/iot/controller/web/MapController.java
  8. 30 0
      src/main/java/cn/minbb/iot/data/ConfigEnum.java
  9. 11 4
      src/main/java/cn/minbb/iot/data/ResponseResult.java
  10. 24 0
      src/main/java/cn/minbb/iot/handler/AccessDenied.java
  11. 44 0
      src/main/java/cn/minbb/iot/handler/AppExceptionHandler.java
  12. 49 0
      src/main/java/cn/minbb/iot/handler/LoginAuthenticationFailureHandler.java
  13. 62 0
      src/main/java/cn/minbb/iot/handler/LoginAuthenticationSuccessHandler.java
  14. 19 0
      src/main/java/cn/minbb/iot/handler/LoginUrlEntryPoint.java
  15. 50 0
      src/main/java/cn/minbb/iot/handler/LogoutSuccessHandler.java
  16. 58 0
      src/main/java/cn/minbb/iot/model/Config.java
  17. 2 2
      src/main/java/cn/minbb/iot/model/Device.java
  18. 1 10
      src/main/java/cn/minbb/iot/model/DeviceData.java
  19. 102 0
      src/main/java/cn/minbb/iot/model/Feedback.java
  20. 85 0
      src/main/java/cn/minbb/iot/model/Log.java
  21. 49 0
      src/main/java/cn/minbb/iot/model/Message.java
  22. 71 6
      src/main/java/cn/minbb/iot/model/User.java
  23. 56 0
      src/main/java/cn/minbb/iot/model/UserRole.java
  24. 15 0
      src/main/java/cn/minbb/iot/model/repository/ConfigRepository.java
  25. 1 1
      src/main/java/cn/minbb/iot/model/repository/DeviceDataRepository.java
  26. 1 1
      src/main/java/cn/minbb/iot/model/repository/DeviceRepository.java
  27. 15 0
      src/main/java/cn/minbb/iot/model/repository/FeedbackRepository.java
  28. 15 0
      src/main/java/cn/minbb/iot/model/repository/LogRepository.java
  29. 7 0
      src/main/java/cn/minbb/iot/model/repository/MessageRepository.java
  30. 1 1
      src/main/java/cn/minbb/iot/model/repository/UserRepository.java
  31. 14 0
      src/main/java/cn/minbb/iot/model/repository/UserRoleRepository.java
  32. 16 0
      src/main/java/cn/minbb/iot/service/ConfigService.java
  33. 5 0
      src/main/java/cn/minbb/iot/service/ConsumeCallback.java
  34. 13 0
      src/main/java/cn/minbb/iot/service/FeedbackService.java
  35. 52 0
      src/main/java/cn/minbb/iot/service/HttpClient.java
  36. 24 0
      src/main/java/cn/minbb/iot/service/LogService.java
  37. 4 0
      src/main/java/cn/minbb/iot/service/MessageService.java
  38. 154 0
      src/main/java/cn/minbb/iot/service/MqttService.java
  39. 15 0
      src/main/java/cn/minbb/iot/service/UserRoleService.java
  40. 2 1
      src/main/java/cn/minbb/iot/service/UserService.java
  41. 51 0
      src/main/java/cn/minbb/iot/service/impl/ConfigServiceImpl.java
  42. 11 0
      src/main/java/cn/minbb/iot/service/impl/ConsumeCallBackImpl.java
  43. 43 0
      src/main/java/cn/minbb/iot/service/impl/FeedbackServiceImpl.java
  44. 128 0
      src/main/java/cn/minbb/iot/service/impl/LogServiceImpl.java
  45. 8 0
      src/main/java/cn/minbb/iot/service/impl/MessageServiceImpl.java
  46. 42 0
      src/main/java/cn/minbb/iot/service/impl/UserRoleServiceImpl.java
  47. 38 0
      src/main/java/cn/minbb/iot/service/impl/UserServiceImpl.java
  48. 10 10
      src/main/java/cn/minbb/iot/task/AutoConfig.java
  49. 56 0
      src/main/java/cn/minbb/iot/util/IPCachePool.java
  50. 63 0
      src/main/java/cn/minbb/iot/util/IPUtil.java
  51. 123 0
      src/main/java/cn/minbb/iot/util/LRUCache.java
  52. 58 0
      src/main/java/cn/minbb/iot/util/SortTools.java
  53. 3 3
      src/main/resources/application.properties
  54. 5 0
      src/main/resources/static/css/bootstrap.min.css
  55. 0 0
      src/main/resources/static/css/bootstrap.min.css.map
  56. 625 0
      src/main/resources/static/css/demo.css
  57. 8187 0
      src/main/resources/static/css/paper-kit.css
  58. 50 0
      src/main/resources/static/css/paper-kit.css.map
  59. 15 0
      src/main/resources/static/css/paper-kit.min.css
  60. BIN
      src/main/resources/static/fonts/nucleo-icons.eot
  61. BIN
      src/main/resources/static/fonts/nucleo-icons.ttf
  62. BIN
      src/main/resources/static/fonts/nucleo-icons.woff
  63. BIN
      src/main/resources/static/fonts/nucleo-icons.woff2
  64. BIN
      src/main/resources/static/images/author.png
  65. BIN
      src/main/resources/static/images/fog-low.png
  66. BIN
      src/main/resources/static/images/index-background.jpg
  67. BIN
      src/main/resources/static/images/yumin.jpg
  68. 5 0
      src/main/resources/static/js/core/bootstrap.min.js
  69. 1 0
      src/main/resources/static/js/core/jquery.min.js
  70. 3 0
      src/main/resources/static/js/core/popper.min.js
  71. 318 0
      src/main/resources/static/js/paper-kit.js
  72. 0 0
      src/main/resources/static/js/paper-kit.js.map
  73. 0 0
      src/main/resources/static/js/paper-kit.min.js
  74. 2707 0
      src/main/resources/static/js/plugins/bootstrap-datepicker.js
  75. 786 0
      src/main/resources/static/js/plugins/bootstrap-switch.js
  76. 5 0
      src/main/resources/static/js/plugins/moment.min.js
  77. 2 0
      src/main/resources/static/js/plugins/nouislider.min.js
  78. 1212 0
      src/main/resources/templates/index.html

+ 27 - 1
pom.xml

@@ -26,7 +26,7 @@
             <artifactId>spring-boot-starter-tomcat</artifactId>
             <scope>provided</scope>
         </dependency>
-        
+
         <!-- Web -->
         <dependency>
             <groupId>org.springframework.boot</groupId>
@@ -65,6 +65,18 @@
             <version>2.3.0</version>
         </dependency>
 
+        <!-- Spring Security -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
         <!-- Swagger2 -->
         <dependency>
             <groupId>io.springfox</groupId>
@@ -85,6 +97,13 @@
             <version>1.2.38</version>
         </dependency>
 
+        <!-- OKHTTP -->
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+            <version>3.9.1</version>
+        </dependency>
+
         <!-- WebSocket -->
         <dependency>
             <groupId>org.springframework.boot</groupId>
@@ -113,6 +132,13 @@
             <artifactId>spring-integration-mqtt</artifactId>
         </dependency>
 
+        <!-- fusesource MQTT -->
+        <dependency>
+            <groupId>org.fusesource.mqtt-client</groupId>
+            <artifactId>mqtt-client</artifactId>
+            <version>1.14</version>
+        </dependency>
+
         <!-- 热部署-->
         <dependency>
             <groupId>org.springframework.boot</groupId>

+ 2 - 2
src/main/java/cn/minbb/iot/config/MqttSenderConfig.java

@@ -52,8 +52,8 @@ public class MqttSenderConfig {
     @Bean
     public MqttConnectOptions getMqttConnectOptions() {
         MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
-        mqttConnectOptions.setUserName(username);
-        mqttConnectOptions.setPassword(password.toCharArray());
+        // mqttConnectOptions.setUserName(username);
+        // mqttConnectOptions.setPassword(password.toCharArray());
         mqttConnectOptions.setServerURIs(new String[]{hostUrl});
         mqttConnectOptions.setKeepAliveInterval(2);
         return mqttConnectOptions;

+ 101 - 0
src/main/java/cn/minbb/iot/config/WebSecurityConfig.java

@@ -0,0 +1,101 @@
+package cn.minbb.iot.config;
+
+import cn.minbb.iot.handler.*;
+import cn.minbb.iot.model.repository.UserRepository;
+import cn.minbb.iot.service.impl.UserServiceImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.BadCredentialsException;
+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.core.session.SessionRegistryImpl;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+
+@Configuration
+@EnableWebSecurity
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+
+    private Logger logger = LoggerFactory.getLogger(WebSecurityConfig.class);
+
+    private UserRepository userRepository;
+    private LoginAuthenticationSuccessHandler loginAuthenticationSuccessHandler;
+    private LoginAuthenticationFailureHandler loginAuthenticationFailureHandler;
+    private LogoutSuccessHandler logoutSuccessHandler;
+
+    @Autowired
+    public WebSecurityConfig(
+            UserRepository userRepository,
+            LoginAuthenticationSuccessHandler loginAuthenticationSuccessHandler,
+            LoginAuthenticationFailureHandler loginAuthenticationFailureHandler,
+            LogoutSuccessHandler logoutSuccessHandler) {
+        this.userRepository = userRepository;
+        this.loginAuthenticationSuccessHandler = loginAuthenticationSuccessHandler;
+        this.loginAuthenticationFailureHandler = loginAuthenticationFailureHandler;
+        this.logoutSuccessHandler = logoutSuccessHandler;
+    }
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        http.exceptionHandling()
+                .authenticationEntryPoint(new LoginUrlEntryPoint())
+                .accessDeniedHandler(new AccessDenied())
+                .and().csrf().disable().authorizeRequests()
+                .antMatchers("/user/config/skin").permitAll()
+                .antMatchers("/interactive/**").access("hasRole('USER')")
+                .antMatchers("/user/**").access("hasRole('USER')")
+                .antMatchers("/admin/**").access("hasRole('USER') and hasRole('ADMIN')")
+                .antMatchers("/admin/config").access("hasRole('USER') and hasRole('ADMIN') and hasRole('SYS_ADMIN')")
+                .antMatchers("/swagger-ui.html").access("hasRole('SYS_ADMIN')")
+                .antMatchers("/css/**", "/js/**", "/images/**", "/fonts/*").permitAll()
+                .and().formLogin().loginPage("/sign-in").loginProcessingUrl("/sign-in")
+                // 用户名字段和密码字段
+                .usernameParameter("username").passwordParameter("password")
+                // 登陆成功后跳转的请求和验证失败后跳转的请求
+                .defaultSuccessUrl("/admin").failureUrl("/sign-in?error=true").permitAll()
+                .successHandler(loginAuthenticationSuccessHandler)
+                .failureHandler(loginAuthenticationFailureHandler)
+                .and().logout().logoutUrl("/sign-out").logoutSuccessUrl("").logoutSuccessHandler(logoutSuccessHandler)
+                // 使 Session 失效
+                .invalidateHttpSession(true)
+                // 清除认证信息
+                .clearAuthentication(true).permitAll()
+                // 开启 cookie 存储用户信息
+                .and().rememberMe().rememberMeParameter("remember").rememberMeCookieName("remember")
+                // cookie 有效期为两个星期(秒)
+                .tokenValiditySeconds(1209600)
+                .and().authorizeRequests()
+                .anyRequest().permitAll()
+                // Session 管理
+                .and().sessionManagement()
+                // 系统中同一个账号的登陆数量限制
+                .maximumSessions(1).sessionRegistry(new SessionRegistryImpl())
+                .and().and().headers().frameOptions().disable()
+                .and().authorizeRequests();
+    }
+
+    @Override
+    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+        auth.userDetailsService(new UserServiceImpl(userRepository)).passwordEncoder(new BCryptPasswordEncoder() {
+            @Override
+            public String encode(CharSequence rawPassword) {
+                logger.info("密码加密 1 = {}", rawPassword);
+                logger.info("密码加密 2 = {}", new BCryptPasswordEncoder().encode(rawPassword));
+                return new BCryptPasswordEncoder().encode(rawPassword);
+            }
+
+            @Override
+            public boolean matches(CharSequence rawPassword, String encodedPassword) {
+                logger.info("密码验证逻辑 3 = {}", rawPassword);
+                logger.info("密码验证逻辑 4 = {}", encodedPassword);
+                logger.info("密码验证逻辑 5 = {}", new BCryptPasswordEncoder().encode(rawPassword));
+                if (!encodedPassword.contentEquals(rawPassword))
+                    throw new BadCredentialsException("密码错误!");
+                return true;
+            }
+        });
+    }
+}

+ 3 - 2
src/main/java/cn/minbb/iot/controller/rest/IoTController.java

@@ -1,5 +1,6 @@
 package cn.minbb.iot.controller.rest;
 
+import cn.minbb.iot.data.ResponseResult;
 import cn.minbb.iot.service.MqttGateway;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -16,7 +17,7 @@ public class IoTController {
     }
 
     @GetMapping("status")
-    public String status() {
-        return "IoT Server is Running...";
+    public ResponseResult<String> status() {
+        return ResponseResult.create().success(true).message("IoT Server is Running...").dataNone();
     }
 }

+ 3 - 3
src/main/java/cn/minbb/iot/controller/rest/UserController.java

@@ -31,14 +31,14 @@ public class UserController {
             User user = userService.findUserByUsername(userClient.getUsername());
             if (user == null) {
                 // 用户不存在
-                result = ResponseResult.ok(false).code(0).message("用户不存在").dataNone();
+                result = ResponseResult.create().success(false).code(0).message("用户不存在").dataNone();
             } else {
                 if (userClient.getPassword().equals(user.getPassword())) {
                     // OK
-                    result = ResponseResult.ok(true).code(1).message("登录成功").data(user);
+                    result = ResponseResult.create().success(true).code(1).message("登录成功").data(user);
                 } else {
                     // 密码错误
-                    result = ResponseResult.ok(false).code(0).message("密码错误").dataNone();
+                    result = ResponseResult.create().success(false).code(0).message("密码错误").dataNone();
                 }
             }
         }

+ 22 - 0
src/main/java/cn/minbb/iot/controller/web/MainController.java

@@ -0,0 +1,22 @@
+package cn.minbb.iot.controller.web;
+
+import cn.minbb.iot.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+@Controller
+@RequestMapping("")
+public class MainController {
+
+    @Autowired
+    UserService userService;
+
+    @GetMapping("")
+    public ModelAndView indexPage(ModelAndView modelAndView) {
+        modelAndView.setViewName("index");
+        return modelAndView;
+    }
+}

+ 1 - 1
src/main/java/cn/minbb/iot/controller/web/MapController.java

@@ -6,7 +6,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.servlet.ModelAndView;
 
 @Controller
-@RequestMapping
+@RequestMapping("map")
 public class MapController {
 
     @GetMapping

+ 30 - 0
src/main/java/cn/minbb/iot/data/ConfigEnum.java

@@ -0,0 +1,30 @@
+package cn.minbb.iot.data;
+
+import lombok.Getter;
+
+import javax.validation.constraints.NotNull;
+
+@Getter
+public enum ConfigEnum {
+
+    // 系统配置
+    NAME("IoT", "系统名称"),
+    ENABLE_REGISTRATION_FUNCTION(true, "启用注册功能"),
+    ENABLE_REGISTRATION_MAIL_NOTIFY(true, "启用注册邮件确认"),
+    ENABLE_VERIFICATION_CODE_SERVICE(true, "启用验证码服务"),
+    SYSTEM_EMAIL_HOST("smtp.exmail.qq.com", "系统发件主机"),
+    SYSTEM_EMAIL_USERNAME("yumin@minbb.cn", "系统发件邮箱账户"),
+    SYSTEM_EMAIL_PASSWORD("TqumoGpdSgxGB3ch", "系统发件邮箱密码"),
+    RECORD_REQUEST_LOG_IN_FILE(true, "记录请求日志(文件)"),
+    RECORD_REQUEST_LOG_IN_DATABASE(false, "记录请求日志(数据库)"),
+    // 用户配置
+    USER_DEFAULT_AVATAR("/images/user-400.png", "用户默认头像");
+
+    Object value;
+    String description;
+
+    ConfigEnum(@NotNull Object value, String description) {
+        this.value = value;
+        this.description = description;
+    }
+}

+ 11 - 4
src/main/java/cn/minbb/iot/data/ResponseResult.java

@@ -22,8 +22,8 @@ public class ResponseResult<T extends Serializable> implements Serializable {
 
     private Collection<T> dataset;
 
-    public static ResponseResult.Builder ok(Boolean success) {
-        return new ResultBuilder(success);
+    public static ResponseResult.Builder create() {
+        return new ResultBuilder();
     }
 
     private static class ResultBuilder implements Builder {
@@ -32,8 +32,7 @@ public class ResponseResult<T extends Serializable> implements Serializable {
         private Boolean success;
         private String message;
 
-        ResultBuilder(boolean success) {
-            this.success = success;
+        ResultBuilder() {
         }
 
         @Override
@@ -42,6 +41,12 @@ public class ResponseResult<T extends Serializable> implements Serializable {
             return this;
         }
 
+        @Override
+        public Builder success(Boolean success) {
+            this.success = success;
+            return this;
+        }
+
         @Override
         public Builder message(String message) {
             this.message = message;
@@ -72,6 +77,8 @@ public class ResponseResult<T extends Serializable> implements Serializable {
     public interface Builder {
         Builder code(Integer code);
 
+        Builder success(Boolean success);
+
         Builder message(String message);
 
         <T extends Serializable> ResponseResult<T> data(T data);

+ 24 - 0
src/main/java/cn/minbb/iot/handler/AccessDenied.java

@@ -0,0 +1,24 @@
+package cn.minbb.iot.handler;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.security.web.WebAttributes;
+import org.springframework.security.web.access.AccessDeniedHandler;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * 当一个已授权(或已登陆)的用户请求访问他权限之外的资源时, handle 方法将会被调用
+ */
+public class AccessDenied implements AccessDeniedHandler {
+
+    @Override
+    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
+        httpServletRequest.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, new Exception("访问权限不足"));
+        httpServletResponse.setStatus(HttpStatus.OK.value());
+        httpServletResponse.sendRedirect("/sign-in?error=true");
+    }
+}

+ 44 - 0
src/main/java/cn/minbb/iot/handler/AppExceptionHandler.java

@@ -0,0 +1,44 @@
+package cn.minbb.iot.handler;
+
+import cn.minbb.iot.data.ResponseResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@RestControllerAdvice
+public class AppExceptionHandler {
+
+    private Logger logger = LoggerFactory.getLogger(AppExceptionHandler.class);
+
+    @ExceptionHandler(value = Exception.class)
+    public Object errorHandler(HttpServletRequest request, HttpServletResponse response, Exception e) throws Exception {
+        e.printStackTrace();
+        String error = "全局捕获异常\n" + e.getMessage();
+        logger.error(error);
+        if (isAjax(request)) {
+            return ResponseResult.create().success(false).code(-1).message(e.getMessage());
+        } else {
+            ModelAndView modelAndView = new ModelAndView();
+            modelAndView.addObject("TITLE", "IoT");
+            modelAndView.addObject("exception", e);
+            modelAndView.addObject("url", request.getRequestURL());
+            modelAndView.setViewName("app-error");
+            return modelAndView;
+        }
+    }
+
+    /**
+     * 判断请求是否为 Ajax 请求
+     *
+     * @param request HttpServletRequest
+     * @return 是否为 Ajax 请求
+     */
+    private boolean isAjax(HttpServletRequest request) {
+        return (null != request.getHeader("X-Requested-With") && "XMLHttpRequest".equals(request.getHeader("X-Requested-With")));
+    }
+}

+ 49 - 0
src/main/java/cn/minbb/iot/handler/LoginAuthenticationFailureHandler.java

@@ -0,0 +1,49 @@
+package cn.minbb.iot.handler;
+
+import cn.minbb.iot.service.LogService;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.WebAttributes;
+import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+@Component
+public class LoginAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
+
+    private Logger logger = LoggerFactory.getLogger(LoginAuthenticationFailureHandler.class);
+
+    private LogService logService;
+    private ObjectMapper objectMapper;
+
+    @Autowired
+    public LoginAuthenticationFailureHandler(LogService logService, ObjectMapper objectMapper) {
+        this.logService = logService;
+        this.objectMapper = objectMapper;
+    }
+
+    @Override
+    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
+        String message = objectMapper.writeValueAsString(exception.getMessage());
+        logService.saveUserAction("用户登陆", message, false, request);
+        logger.info("用户登录失败 = {}", message);
+        if (false) {
+            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
+            response.setContentType("application/json;charset=UTF-8");
+            response.getWriter().write(objectMapper.writeValueAsString(exception.getMessage()));
+        } else {
+            // 异常写入 Session
+            request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception);
+            response.setStatus(HttpStatus.OK.value());
+            response.sendRedirect("/sign-in?error=true");
+        }
+    }
+}

+ 62 - 0
src/main/java/cn/minbb/iot/handler/LoginAuthenticationSuccessHandler.java

@@ -0,0 +1,62 @@
+package cn.minbb.iot.handler;
+
+import cn.minbb.iot.service.LogService;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
+import org.springframework.security.web.savedrequest.SavedRequest;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+@Component
+public class LoginAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
+
+    private Logger logger = LoggerFactory.getLogger(LoginAuthenticationSuccessHandler.class);
+
+    private LogService logService;
+    private ObjectMapper objectMapper;
+
+    @Autowired
+    public LoginAuthenticationSuccessHandler(LogService logService, ObjectMapper objectMapper) {
+        this.logService = logService;
+        this.objectMapper = objectMapper;
+    }
+
+    // Authentication 封装认证信息
+    @Override
+    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException {
+        String auth = objectMapper.writeValueAsString(authentication);
+        logService.saveUserAction("用户登陆", auth, true, request);
+        logger.info("用户登陆成功 = {}", auth);
+        // 登录方式不同,Authentication 不同
+        if (false) {
+            response.setContentType("application/json;charset=UTF-8");
+            // 把 authentication 对象转成 json 格式字符串通过 response 以 application/json;charset=UTF-8 格式写到响应里面去
+            response.getWriter().write(objectMapper.writeValueAsString(authentication));
+        } else {
+            // 跳转到登录之前访问的页面
+            response.setStatus(HttpStatus.OK.value());
+            SavedRequest savedRequest = (SavedRequest) request.getSession().getAttribute("SPRING_SECURITY_SAVED_REQUEST");
+            if (savedRequest != null) {
+                response.sendRedirect(savedRequest.getRedirectUrl());
+                request.getSession().removeAttribute("SPRING_SECURITY_SAVED_REQUEST");
+            } else {
+                // 重定向页面需要在登录页设置路径参数
+                String redirect = (String) request.getSession().getAttribute("REDIRECT");
+                if (null != redirect) {
+                    response.sendRedirect(redirect);
+                } else {
+                    response.sendRedirect("/");
+                }
+            }
+        }
+    }
+}

+ 19 - 0
src/main/java/cn/minbb/iot/handler/LoginUrlEntryPoint.java

@@ -0,0 +1,19 @@
+package cn.minbb.iot.handler;
+
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.AuthenticationEntryPoint;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * 当一个未授权的用户请求非公有资源时, commence 方法将会被调用
+ */
+public class LoginUrlEntryPoint implements AuthenticationEntryPoint {
+    @Override
+    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
+        httpServletResponse.sendRedirect("/sign-in");
+    }
+}

+ 50 - 0
src/main/java/cn/minbb/iot/handler/LogoutSuccessHandler.java

@@ -0,0 +1,50 @@
+package cn.minbb.iot.handler;
+
+import cn.minbb.iot.service.LogService;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * SimpleUrlLogoutSuccessHandler - 重定向到设置的URL地址。默认的地址是/login?logout
+ * HttpStatusReturningLogoutSuccessHandler - REST API场景,允许设置一个返回给客户端的HTTP状态码(默认返回200)来替换重定向到URL这个动作
+ */
+@Component
+public class LogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
+
+    private Logger logger = LoggerFactory.getLogger(LogoutSuccessHandler.class);
+
+    private LogService logService;
+    private ObjectMapper objectMapper;
+
+    @Autowired
+    public LogoutSuccessHandler(LogService logService, ObjectMapper objectMapper) {
+        this.logService = logService;
+        this.objectMapper = objectMapper;
+    }
+
+    @Override
+    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
+        String auth = objectMapper.writeValueAsString(authentication);
+        logService.saveUserAction("用户登出", auth, true, request);
+        logger.info("用户登出成功 = {}", auth);
+        if (false) {
+            response.setContentType("application/json;charset=UTF-8");
+            response.getWriter().write(objectMapper.writeValueAsString(authentication));
+        } else {
+            response.setStatus(HttpStatus.OK.value());
+            response.sendRedirect("/sign-in?logout=true");
+            super.onLogoutSuccess(request, response, authentication);
+        }
+    }
+}

+ 58 - 0
src/main/java/cn/minbb/iot/model/Config.java

@@ -0,0 +1,58 @@
+package cn.minbb.iot.model;
+
+import cn.minbb.iot.data.ConfigEnum;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+
+@Entity
+@Table(name = "config",
+        uniqueConstraints = {@UniqueConstraint(name = "unique_name", columnNames = {"name"})},
+        indexes = {@Index(name = "index_name", columnList = "name")})
+@NoArgsConstructor
+public class Config implements Serializable {
+
+    @Getter
+    @Setter
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id", nullable = false, columnDefinition = "INTEGER COMMENT '用户'")
+    private Integer id;
+
+    @Getter
+    @Setter
+    @Enumerated(EnumType.STRING)
+    @Column(name = "name", nullable = false, columnDefinition = "VARCHAR(64) COMMENT '配置项'")
+    private ConfigEnum name;
+
+    @Getter
+    @Setter
+    @Column(name = "value", nullable = false, columnDefinition = "VARCHAR(255) COMMENT '配置值'")
+    private String value;
+
+    @Getter
+    @Setter
+    @Column(name = "description", nullable = false, columnDefinition = "VARCHAR(255) COMMENT '描述'")
+    private String description;
+
+    @Getter
+    @Setter
+    @Column(name = "updated_at", columnDefinition = "DATETIME COMMENT '更新时间'")
+    @UpdateTimestamp
+    private Date updatedAt;
+
+    @Version
+    @Column(name = "version", columnDefinition = "INTEGER COMMENT '版本号'")
+    public Integer version;
+
+    public Config(ConfigEnum name, String value, String description) {
+        this.name = name;
+        this.value = value;
+        this.description = description;
+    }
+}

+ 2 - 2
src/main/java/cn/minbb/iot/model/Device.java

@@ -20,7 +20,7 @@ public class Device implements Serializable {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     @Column(name = "id", nullable = false, columnDefinition = "INT COMMENT '设备实体ID'")
-    private Long id;
+    private Integer id;
 
     @Getter
     @Setter
@@ -51,5 +51,5 @@ public class Device implements Serializable {
 
     @Version
     @Column(name = "version", columnDefinition = "BIGINT COMMENT '版本号'")
-    public Long version;
+    public Integer version;
 }

+ 1 - 10
src/main/java/cn/minbb/iot/model/DeviceData.java

@@ -19,7 +19,7 @@ public class DeviceData implements Serializable {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     @Column(name = "id", nullable = false, columnDefinition = "INT COMMENT '设备数据实体ID'")
-    private Long id;
+    private Integer id;
 
     @Getter
     @Setter
@@ -56,11 +56,6 @@ public class DeviceData implements Serializable {
     @Column(name = "gps_time", columnDefinition = "FLOAT COMMENT 'GPS时间'")
     private Float gpsTime;
 
-    @Getter
-    @Setter
-    @Column(name = "bei_jing_time", columnDefinition = "INTEGER COMMENT '北京时间'")
-    private Integer beiJingTime;
-
     @Getter
     @Setter
     @Column(name = "remark", columnDefinition = "VARCHAR(64) COMMENT '备注'")
@@ -77,10 +72,6 @@ public class DeviceData implements Serializable {
     @CreationTimestamp
     private Date createdAt;
 
-    @Version
-    @Column(name = "version", columnDefinition = "BIGINT COMMENT '版本号'")
-    public Long version;
-
     public DeviceData(String longitude, String latitude, String remark) {
         this.longitude = longitude;
         this.latitude = latitude;

+ 102 - 0
src/main/java/cn/minbb/iot/model/Feedback.java

@@ -0,0 +1,102 @@
+package cn.minbb.iot.model;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+
+@Entity
+@Table(name = "feedback", indexes = {
+        @Index(name = "index_status", columnList = "status"),
+        @Index(name = "index_user_id", columnList = "user_id"),
+        @Index(name = "index_is_enabled", columnList = "is_enabled"),
+})
+@NoArgsConstructor
+public class Feedback implements Serializable {
+
+    @Getter
+    @Setter
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id", nullable = false, columnDefinition = "INTEGER COMMENT '反馈'")
+    private Integer id;
+
+    @Getter
+    @Setter
+    @Column(name = "content", columnDefinition = "TEXT COMMENT '内容'")
+    private String content;
+
+    @Getter
+    @Setter
+    @Column(name = "type", columnDefinition = "VARCHAR(255) COMMENT '类型'")
+    private String type;
+
+    @Getter
+    @Setter
+    @Column(name = "problem", columnDefinition = "VARCHAR(255) COMMENT '问题'")
+    private String problem;
+
+    @Getter
+    @Setter
+    @Column(name = "person_name", columnDefinition = "VARCHAR(255) COMMENT '反馈人姓名'")
+    private String personName;
+
+    @Getter
+    @Setter
+    @Column(name = "person_contact", columnDefinition = "VARCHAR(255) COMMENT '反馈人联系方式'")
+    private String personContact;
+
+    @Getter
+    @Setter
+    @Column(name = "remark", nullable = true, columnDefinition = "VARCHAR(255) COMMENT '备注'")
+    private String remark;
+
+    @Getter
+    @Setter
+    @Column(name = "status", columnDefinition = "VARCHAR(32) COMMENT '内容状态'")
+    private String status;
+
+    @Getter
+    @Setter
+    @Column(name = "user_id", nullable = true, columnDefinition = "INTEGER COMMENT '关联用户'")
+    private Integer userId;
+
+    @Getter
+    @Setter
+    @Column(name = "is_dealt", nullable = false, columnDefinition = "TINYINT DEFAULT '0' COMMENT '已处理'")
+    private Boolean isDealt;
+
+    @Getter
+    @Setter
+    @Column(name = "is_enabled", nullable = false, columnDefinition = "TINYINT DEFAULT '1' COMMENT '启用'")
+    private Boolean isEnabled;
+
+    @Getter
+    @Setter
+    @Column(name = "created_at", columnDefinition = "DATETIME COMMENT '创建时间'")
+    @CreationTimestamp
+    private Date createdAt;
+
+    @Getter
+    @Setter
+    @Column(name = "updated_at", columnDefinition = "DATETIME COMMENT '更新时间'")
+    @UpdateTimestamp
+    private Date updatedAt;
+
+    @Version
+    @Column(name = "version", columnDefinition = "INTEGER COMMENT '版本号'")
+    public Integer version;
+
+    public Feedback(String content, String type, String problem, String personName, String personContact) {
+        this.content = content;
+        this.type = type;
+        this.problem = problem;
+        this.personName = personName;
+        this.personContact = personContact;
+    }
+}

+ 85 - 0
src/main/java/cn/minbb/iot/model/Log.java

@@ -0,0 +1,85 @@
+package cn.minbb.iot.model;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.hibernate.annotations.CreationTimestamp;
+
+import javax.persistence.*;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.Date;
+
+@Entity
+@Table(name = "log",
+        indexes = {
+                @Index(name = "index_action", columnList = "action"),
+                @Index(name = "index_success", columnList = "success"),
+                @Index(name = "index_remark", columnList = "remark"),
+                @Index(name = "index_user_id", columnList = "user_id"),
+                @Index(name = "index_ip", columnList = "ip"),
+                @Index(name = "index_created_at", columnList = "created_at"),
+        })
+@NoArgsConstructor
+public class Log implements Serializable {
+
+    @Getter
+    @Setter
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id", nullable = false, columnDefinition = "INTEGER COMMENT '日志'")
+    private Integer id;
+
+    @Getter
+    @Setter
+    @Column(name = "action", nullable = false, columnDefinition = "VARCHAR(255) COMMENT '动作'")
+    private String action;
+
+    @Getter
+    @Setter
+    @Column(name = "data", nullable = false, columnDefinition = "TEXT COMMENT '产生的数据'")
+    private String data;
+
+    @Getter
+    @Setter
+    @Column(name = "success", nullable = false, columnDefinition = "TINYINT COMMENT '执行是否成功'")
+    private Boolean success;
+
+    @Getter
+    @Setter
+    @Column(name = "remark", nullable = true, columnDefinition = "VARCHAR(255) COMMENT '备注'")
+    private String remark;
+
+    @Getter
+    @Setter
+    @Column(name = "user_id", nullable = true, columnDefinition = "INTEGER COMMENT '关联用户'")
+    private Integer userId;
+
+    @Getter
+    @Setter
+    @Column(name = "ip", nullable = false, columnDefinition = "VARCHAR(16) COMMENT '日志产生的IP'")
+    private String ip;
+
+    @Getter
+    @Setter
+    @Column(name = "created_at", columnDefinition = "DATETIME COMMENT '创建时间'")
+    @CreationTimestamp
+    private Date createdAt;
+
+    public Log(@NotNull String action, @NotNull String data, @NotNull Boolean success, String remark, @NotNull String ip) {
+        this.action = action;
+        this.data = data;
+        this.success = success;
+        this.remark = remark;
+        this.ip = ip;
+    }
+
+    public Log(@NotNull String action, @NotNull String data, @NotNull Boolean success, String remark, Integer userId, @NotNull String ip) {
+        this.action = action;
+        this.data = data;
+        this.success = success;
+        this.remark = remark;
+        this.userId = userId;
+        this.ip = ip;
+    }
+}

+ 49 - 0
src/main/java/cn/minbb/iot/model/Message.java

@@ -0,0 +1,49 @@
+package cn.minbb.iot.model;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.hibernate.annotations.CreationTimestamp;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+
+@Entity
+@Table(name = "message", indexes = {@Index(name = "index_user_id", columnList = "user_id")})
+@NoArgsConstructor
+public class Message implements Serializable {
+
+    @Getter
+    @Setter
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id", nullable = false, columnDefinition = "INT COMMENT '消息'")
+    private Integer id;
+
+    @Getter
+    @Setter
+    @Column(name = "content", nullable = false, columnDefinition = "VARCHAR(1000) COMMENT '消息内容'")
+    private String content;
+
+    @Getter
+    @Setter
+    @Column(name = "is_read", nullable = false, columnDefinition = "TINYINT COMMENT '已读'")
+    private Boolean isRead;
+
+    @Getter
+    @Setter
+    @Column(name = "remark", nullable = true, columnDefinition = "VARCHAR(255) COMMENT '备注'")
+    private String remark;
+
+    @Getter
+    @Setter
+    @Column(name = "user_id", nullable = true, columnDefinition = "INTEGER COMMENT '关联用户'")
+    private Integer userId;
+
+    @Getter
+    @Setter
+    @Column(name = "created_at", columnDefinition = "DATETIME COMMENT '创建时间'")
+    @CreationTimestamp
+    private Date createdAt;
+}

+ 71 - 6
src/main/java/cn/minbb/iot/model/User.java

@@ -5,23 +5,25 @@ import lombok.NoArgsConstructor;
 import lombok.Setter;
 import org.hibernate.annotations.CreationTimestamp;
 import org.hibernate.annotations.UpdateTimestamp;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
 
 import javax.persistence.*;
 import javax.validation.constraints.NotNull;
-import java.io.Serializable;
-import java.util.Date;
+import java.util.*;
 
 @Entity
 @Table(name = "user")
 @NoArgsConstructor
-public class User implements Serializable {
+public class User implements UserDetails {
 
     @Getter
     @Setter
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     @Column(name = "id", nullable = false, columnDefinition = "INT COMMENT '用户实体ID'")
-    private Long id;
+    private Integer id;
 
     @Getter
     @Setter
@@ -43,11 +45,36 @@ public class User implements Serializable {
     @Column(name = "avatar", columnDefinition = "VARCHAR(255) COMMENT '头像'")
     private String avatar;
 
+    @Getter
+    @Setter
+    @Column(name = "email", columnDefinition = "VARCHAR(255) COMMENT '电子邮箱'")
+    private String email;
+
     @Getter
     @Setter
     @Column(name = "phone", columnDefinition = "VARCHAR(16) COMMENT '手机号'")
     private String phone;
 
+    @Getter
+    @Setter
+    @Column(name = "is_account_non_expired", nullable = false, columnDefinition = "TINYINT DEFAULT '1' COMMENT '帐户未过期'")
+    private Boolean isAccountNonExpired;
+
+    @Getter
+    @Setter
+    @Column(name = "is_account_non_locked", nullable = false, columnDefinition = "TINYINT DEFAULT '1' COMMENT '帐户未锁定'")
+    private Boolean isAccountNonLocked;
+
+    @Getter
+    @Setter
+    @Column(name = "is_credentials_non_expired", nullable = false, columnDefinition = "TINYINT DEFAULT '1' COMMENT '凭据未过期'")
+    private Boolean isCredentialsNonExpired;
+
+    @Getter
+    @Setter
+    @Column(name = "is_enabled", nullable = false, columnDefinition = "TINYINT DEFAULT '1' COMMENT '帐户已启用'")
+    private Boolean isEnabled;
+
     @Getter
     @Setter
     @Column(name = "created_at", columnDefinition = "DATETIME COMMENT '创建时间'")
@@ -61,8 +88,46 @@ public class User implements Serializable {
     private Date updatedAt;
 
     @Version
-    @Column(name = "version", columnDefinition = "BIGINT COMMENT '版本号'")
-    public Long version;
+    @Column(name = "version", columnDefinition = "INT COMMENT '版本号'")
+    public Integer version;
+
+    @Getter
+    @Setter
+    @ManyToMany(cascade = {CascadeType.REFRESH}, fetch = FetchType.EAGER)
+    @JoinTable(name = "user_user_role",
+            joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
+            inverseJoinColumns = {@JoinColumn(name = "user_role_id", referencedColumnName = "id")}
+    )
+    private Set<UserRole> userRoleSet;
+
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+        List<GrantedAuthority> grantedAuthorityList = new ArrayList<>();
+        for (UserRole userRole : this.getUserRoleSet()) {
+            grantedAuthorityList.add(new SimpleGrantedAuthority("ROLE_" + userRole.getRole().name()));
+        }
+        return grantedAuthorityList;
+    }
+
+    @Override
+    public boolean isAccountNonExpired() {
+        return this.isAccountNonExpired;
+    }
+
+    @Override
+    public boolean isAccountNonLocked() {
+        return this.isAccountNonLocked;
+    }
+
+    @Override
+    public boolean isCredentialsNonExpired() {
+        return this.isCredentialsNonExpired;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return this.isEnabled;
+    }
 
     public User(@NotNull String username, @NotNull String password) {
         this.username = username;

+ 56 - 0
src/main/java/cn/minbb/iot/model/UserRole.java

@@ -0,0 +1,56 @@
+package cn.minbb.iot.model;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import javax.persistence.*;
+import java.io.Serializable;
+
+@Entity
+@Table(name = "user_role",
+        uniqueConstraints = {@UniqueConstraint(name = "unique_role", columnNames = {"role"})},
+        indexes = {@Index(name = "index_role", columnList = "role")})
+@NoArgsConstructor
+public class UserRole implements Serializable {
+
+    @Getter
+    @Setter
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id", nullable = false, columnDefinition = "INT COMMENT '用户角色'")
+    private Integer id;
+
+    @Getter
+    @Setter
+    @Enumerated(EnumType.STRING)
+    @Column(name = "role", nullable = false, columnDefinition = "VARCHAR(32) COMMENT '角色名称'")
+    private Role role;
+
+    @Getter
+    @Setter
+    @Column(name = "description", columnDefinition = "VARCHAR(255) COMMENT '角色描述'")
+    private String description;
+
+    public UserRole(Role role) {
+        this.role = role;
+    }
+
+    public UserRole(Role role, String description) {
+        this.role = role;
+        this.description = description;
+    }
+
+    @Getter
+    public enum Role {
+        USER("普通用户(无特殊权限)"),
+        ADMIN("管理员(登录和管理后台)"),
+        SYS_ADMIN("系统管理员(修改系统设置)");
+
+        String description;
+
+        Role(String description) {
+            this.description = description;
+        }
+    }
+}

+ 15 - 0
src/main/java/cn/minbb/iot/model/repository/ConfigRepository.java

@@ -0,0 +1,15 @@
+package cn.minbb.iot.model.repository;
+
+import cn.minbb.iot.data.ConfigEnum;
+import cn.minbb.iot.model.Config;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface ConfigRepository extends JpaRepository<Config, Integer> {
+    Config findOneByName(ConfigEnum configEnum);
+
+    List<Config> findAllByNameIn(List<String> nameList);
+}

+ 1 - 1
src/main/java/cn/minbb/iot/model/repository/DeviceDataRepository.java

@@ -3,5 +3,5 @@ package cn.minbb.iot.model.repository;
 import cn.minbb.iot.model.DeviceData;
 import org.springframework.data.jpa.repository.JpaRepository;
 
-public interface DeviceDataRepository extends JpaRepository<DeviceData, Long> {
+public interface DeviceDataRepository extends JpaRepository<DeviceData, Integer> {
 }

+ 1 - 1
src/main/java/cn/minbb/iot/model/repository/DeviceRepository.java

@@ -3,5 +3,5 @@ package cn.minbb.iot.model.repository;
 import cn.minbb.iot.model.Device;
 import org.springframework.data.jpa.repository.JpaRepository;
 
-public interface DeviceRepository extends JpaRepository<Device, Long> {
+public interface DeviceRepository extends JpaRepository<Device, Integer> {
 }

+ 15 - 0
src/main/java/cn/minbb/iot/model/repository/FeedbackRepository.java

@@ -0,0 +1,15 @@
+package cn.minbb.iot.model.repository;
+
+import cn.minbb.iot.model.Feedback;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface FeedbackRepository extends JpaRepository<Feedback, Integer> {
+    Feedback findOneByIdAndIsEnabledTrue(Integer id);
+
+    List<Feedback> findAllByIsEnabledTrue(Sort sort);
+}

+ 15 - 0
src/main/java/cn/minbb/iot/model/repository/LogRepository.java

@@ -0,0 +1,15 @@
+package cn.minbb.iot.model.repository;
+
+import cn.minbb.iot.model.Log;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.Date;
+import java.util.List;
+
+@Repository
+public interface LogRepository extends JpaRepository<Log, Integer> {
+    List<Log> findByActionAndDataAndCreatedAtBetween(String action, String data, Date start, Date end);
+
+    List<Log> findByDataContaining(String data);
+}

+ 7 - 0
src/main/java/cn/minbb/iot/model/repository/MessageRepository.java

@@ -0,0 +1,7 @@
+package cn.minbb.iot.model.repository;
+
+import cn.minbb.iot.model.Message;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface MessageRepository extends JpaRepository<Message, Integer> {
+}

+ 1 - 1
src/main/java/cn/minbb/iot/model/repository/UserRepository.java

@@ -3,6 +3,6 @@ package cn.minbb.iot.model.repository;
 import cn.minbb.iot.model.User;
 import org.springframework.data.jpa.repository.JpaRepository;
 
-public interface UserRepository extends JpaRepository<User, Long> {
+public interface UserRepository extends JpaRepository<User, Integer> {
     User findOneByUsername(String username);
 }

+ 14 - 0
src/main/java/cn/minbb/iot/model/repository/UserRoleRepository.java

@@ -0,0 +1,14 @@
+package cn.minbb.iot.model.repository;
+
+import cn.minbb.iot.model.UserRole;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.Set;
+
+@Repository
+public interface UserRoleRepository extends JpaRepository<UserRole, Integer> {
+    UserRole findOneByRole(UserRole.Role role);
+
+    Set<UserRole> findAllByRoleIn(Set<UserRole.Role> roleSet);
+}

+ 16 - 0
src/main/java/cn/minbb/iot/service/ConfigService.java

@@ -0,0 +1,16 @@
+package cn.minbb.iot.service;
+
+import cn.minbb.iot.data.ConfigEnum;
+import cn.minbb.iot.model.Config;
+
+import java.util.List;
+
+public interface ConfigService {
+    Config saveOne(Config config);
+
+    List<Config> saveAll(List<Config> configList);
+
+    Config findOneByKey(ConfigEnum configEnum);
+
+    List<Config> findAllByNameList(List<String> nameList);
+}

+ 5 - 0
src/main/java/cn/minbb/iot/service/ConsumeCallback.java

@@ -0,0 +1,5 @@
+package cn.minbb.iot.service;
+
+public interface ConsumeCallback {
+	void onReceived(String topic, String message);
+}

+ 13 - 0
src/main/java/cn/minbb/iot/service/FeedbackService.java

@@ -0,0 +1,13 @@
+package cn.minbb.iot.service;
+
+import cn.minbb.iot.model.Feedback;
+
+import java.util.List;
+
+public interface FeedbackService {
+    Feedback saveOne(Feedback feedback);
+
+    List<Feedback> findAll();
+
+    void deleteOneById(Integer id);
+}

+ 52 - 0
src/main/java/cn/minbb/iot/service/HttpClient.java

@@ -0,0 +1,52 @@
+package cn.minbb.iot.service;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.util.MultiValueMap;
+import org.springframework.util.concurrent.ListenableFuture;
+import org.springframework.util.concurrent.ListenableFutureCallback;
+import org.springframework.web.client.AsyncRestTemplate;
+import org.springframework.web.client.RestTemplate;
+
+@Service
+public class HttpClient {
+
+    private static Logger logger = LoggerFactory.getLogger(HttpClient.class);
+
+    public String client(String url, HttpMethod httpMethod, MultiValueMap<String, String> params) {
+        ResponseEntity<String> stringResponseEntity = null;
+        try {
+            RestTemplate restTemplate = new RestTemplate();
+            stringResponseEntity = restTemplate.getForEntity(url, String.class);
+        } catch (Exception e) {
+            logger.error("{} - {}", e.getCause(), e.getMessage());
+        }
+        return stringResponseEntity != null ? stringResponseEntity.getBody() : null;
+    }
+
+    public void asyncClient(String url, HttpMethod httpMethod, MultiValueMap<String, String> params, AsyncClientCallback asyncClientCallback) {
+        AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate();
+        ListenableFuture<ResponseEntity<String>> forEntity = asyncRestTemplate.getForEntity(url, String.class);
+        forEntity.addCallback(new ListenableFutureCallback<ResponseEntity<String>>() {
+            @Override
+            public void onFailure(Throwable throwable) {
+                asyncClientCallback.onFailure(throwable);
+            }
+
+            @Override
+            public void onSuccess(ResponseEntity<String> stringResponseEntity) {
+                stringResponseEntity.getBody();
+                asyncClientCallback.onSuccess(stringResponseEntity);
+            }
+        });
+    }
+
+    public interface AsyncClientCallback {
+        void onFailure(Throwable throwable);
+
+        void onSuccess(ResponseEntity<String> stringResponseEntity);
+    }
+}

+ 24 - 0
src/main/java/cn/minbb/iot/service/LogService.java

@@ -0,0 +1,24 @@
+package cn.minbb.iot.service;
+
+import cn.minbb.iot.model.Log;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Date;
+import java.util.List;
+
+public interface LogService {
+    Log save(Log log);
+
+    List<Log> findByActionAndDataAndCreatedAtBetween(String action, String data, Date start, Date end);
+
+    List<Log> findByDataContaining(String data);
+
+    /**
+     * 记录页面访问日志
+     *
+     * @param request 页面请求
+     */
+    public void saveViewPage(HttpServletRequest request);
+
+    public void saveUserAction(String action, String data, Boolean success, HttpServletRequest request);
+}

+ 4 - 0
src/main/java/cn/minbb/iot/service/MessageService.java

@@ -0,0 +1,4 @@
+package cn.minbb.iot.service;
+
+public interface MessageService {
+}

+ 154 - 0
src/main/java/cn/minbb/iot/service/MqttService.java

@@ -0,0 +1,154 @@
+package cn.minbb.iot.service;
+
+import org.fusesource.hawtbuf.Buffer;
+import org.fusesource.hawtbuf.UTF8Buffer;
+import org.fusesource.mqtt.client.*;
+import org.springframework.stereotype.Component;
+
+@Component
+public class MqttService {
+
+    private String host = "tcp://my.minbb.cn:1883";
+    private CallbackConnection callbackConnection = null;
+    private BlockingConnection blockingConnection = null;
+
+    MqttService() throws Exception {
+//        host = System.getProperties().getProperty("mqtt.url");
+//        if (host == null || "".equals(host)) {
+//            throw new NullPointerException("The mqtt.url cannot be empty! please assign a value in JVM Property.");
+//        }
+        initCallbackConnection();
+        initBlockingConnection();
+    }
+
+    /**
+     * 初始化回调连接
+     *
+     * @throws Exception
+     */
+    private void initCallbackConnection() throws Exception {
+        MQTT mqtt = new MQTT();
+        mqtt.setHost(host);
+        mqtt.setClientId("IoT_MQTT");
+        mqtt.setReconnectAttemptsMax(1);
+        callbackConnection = mqtt.callbackConnection();
+        callbackConnection.connect(new Callback<Void>() {
+            @Override
+            public void onSuccess(Void value) {
+                System.out.println("callbackConnection连接成功!");
+            }
+
+            @Override
+            public void onFailure(Throwable value) {
+                value.printStackTrace();
+            }
+        });
+    }
+
+    /**
+     * 初始化阻塞连接
+     *
+     * @throws Exception
+     */
+    private void initBlockingConnection() throws Exception {
+        MQTT mqtt = new MQTT();
+        mqtt.setHost(host);
+        mqtt.setClientId("IoT_MQTT");
+        /**
+         * 慎用此参数,当为-1(默认)时,对于blockingConnection会产生publish阻塞,一直阻塞到mqtt服务恢复,会自动重连,方可发送
+         * 对于callbackConnection没影响,应该设置为1
+         * 当不为n(!=-1)时,若mqtt服务器宕机,重试n次,blockingConnection会阻塞解除,但mqtt服务恢复后,无法自动重连,消息无法发送,
+         * 会抛Connection refused异常,同时也影响callbackConnection不会自动重连继续发送
+         */
+        mqtt.setReconnectAttemptsMax(1);
+        blockingConnection = mqtt.blockingConnection();
+        // 阻塞方法,直至连接上否则会一直等待
+        blockingConnection.connect();
+        System.out.println("blockingConnection连接成功!");
+    }
+
+    /**
+     * 异步发送
+     *
+     * @param topic    主题
+     * @param body     消息体
+     * @param qoS      消息服务级别
+     * @param callback 回调接口
+     */
+    public void publishAsync(final String topic, final String body, final QoS qoS, final Callback callback) {
+        callbackConnection.publish(topic, body.getBytes(), qoS, false, callback);
+    }
+
+    /**
+     * 同步发送
+     *
+     * @param topic 主题 & 消息服务级别
+     * @param body  消息体
+     */
+    public void publishSync(Topic topic, String body) {
+        if (body == null || "".equals(body)) return;
+        try {
+            blockingConnection.publish(topic.name().toString(), body.getBytes(), topic.qos(), false);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    void subscribeAsync(Topic[] topics, ConsumeCallback consumeCallback) {
+        callbackConnection.listener(new Listener() {
+            @Override
+            public void onConnected() {
+            }
+
+            @Override
+            public void onDisconnected() {
+                System.out.println("---");
+            }
+
+            @Override
+            public void onPublish(UTF8Buffer utf8Buffer, Buffer buffer, Runnable runnable) {
+                try {
+                    consumeCallback.onReceived(utf8Buffer.toString(), new String(buffer.toByteArray()));
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+                runnable.run();
+            }
+
+            @Override
+            public void onFailure(Throwable throwable) {
+                throwable.printStackTrace();
+            }
+        });
+        callbackConnection.subscribe(topics, new Callback<byte[]>() {
+            @Override
+            public void onSuccess(byte[] value) {
+                for (Topic topic : topics) {
+                    System.out.println(topic.name() + "订阅成功!");
+                }
+            }
+
+            @Override
+            public void onFailure(Throwable value) {
+                System.out.println("订阅失败!");
+                value.printStackTrace();
+            }
+        });
+    }
+
+    public void subscriptSync(Topic[] topics, ConsumeCallback consumeCallback) throws Exception {
+        blockingConnection.subscribe(topics);
+        while (true) {
+            // 对于blockingConnection不能把receive写到try里面,否则mqtt宕机后会出现死循环
+            Message message = blockingConnection.receive();
+            try {
+                consumeCallback.onReceived(message.getTopic(), new String(message.getPayload()));
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            message.ack();
+            System.out.println("--------------");
+
+        }
+    }
+}

+ 15 - 0
src/main/java/cn/minbb/iot/service/UserRoleService.java

@@ -0,0 +1,15 @@
+package cn.minbb.iot.service;
+
+import cn.minbb.iot.model.UserRole;
+
+import java.util.Set;
+
+public interface UserRoleService {
+    UserRole saveOne(UserRole userRole);
+
+    UserRole findOneByRole(UserRole.Role role);
+
+    Set<UserRole> findAll();
+
+    Set<UserRole> findAllByRoleSet(Set<UserRole.Role> roleSet);
+}

+ 2 - 1
src/main/java/cn/minbb/iot/service/UserService.java

@@ -1,8 +1,9 @@
 package cn.minbb.iot.service;
 
 import cn.minbb.iot.model.User;
+import org.springframework.security.core.userdetails.UserDetailsService;
 
-public interface UserService {
+public interface UserService extends UserDetailsService {
     User saveOne(User user);
 
     User findUserByUsername(String username);

+ 51 - 0
src/main/java/cn/minbb/iot/service/impl/ConfigServiceImpl.java

@@ -0,0 +1,51 @@
+package cn.minbb.iot.service.impl;
+
+import cn.minbb.iot.data.ConfigEnum;
+import cn.minbb.iot.model.Config;
+import cn.minbb.iot.model.repository.ConfigRepository;
+import cn.minbb.iot.service.ConfigService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheConfig;
+import org.springframework.cache.annotation.CachePut;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+@CacheConfig(cacheNames = "Config")
+public class ConfigServiceImpl implements ConfigService {
+
+    private ConfigRepository configRepository;
+
+    @Autowired
+    public ConfigServiceImpl(ConfigRepository configRepository) {
+        this.configRepository = configRepository;
+    }
+
+    @CachePut(key = "#config.name")
+    @Override
+    public Config saveOne(Config config) {
+        return configRepository.save(config);
+    }
+
+    @CachePut
+    @Override
+    public List<Config> saveAll(List<Config> configList) {
+        return configRepository.saveAll(configList);
+    }
+
+    @Cacheable(key = "#configEnum.name()")
+    @Override
+    public Config findOneByKey(ConfigEnum configEnum) {
+        return configRepository.findOneByName(configEnum);
+    }
+
+    @Cacheable
+    @Override
+    public List<Config> findAllByNameList(List<String> nameList) {
+        if (nameList.isEmpty()) return new ArrayList<>();
+        return configRepository.findAllByNameIn(nameList);
+    }
+}

+ 11 - 0
src/main/java/cn/minbb/iot/service/impl/ConsumeCallBackImpl.java

@@ -0,0 +1,11 @@
+package cn.minbb.iot.service.impl;
+
+import cn.minbb.iot.service.ConsumeCallback;
+
+public class ConsumeCallBackImpl implements ConsumeCallback {
+    @Override
+    public void onReceived(String topic, String message) {
+        System.out.println("topic:" + topic);
+        System.out.println("message:" + message);
+    }
+}

+ 43 - 0
src/main/java/cn/minbb/iot/service/impl/FeedbackServiceImpl.java

@@ -0,0 +1,43 @@
+package cn.minbb.iot.service.impl;
+
+import cn.minbb.iot.model.Feedback;
+import cn.minbb.iot.model.repository.FeedbackRepository;
+import cn.minbb.iot.service.FeedbackService;
+import cn.minbb.iot.util.SortTools;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class FeedbackServiceImpl implements FeedbackService {
+
+    private FeedbackRepository feedbackRepository;
+
+    @Autowired
+    public FeedbackServiceImpl(FeedbackRepository feedbackRepository) {
+        this.feedbackRepository = feedbackRepository;
+    }
+
+    @Override
+    public Feedback saveOne(Feedback feedback) {
+        feedback.setIsDealt(false);
+        feedback.setIsEnabled(true);
+        return feedbackRepository.save(feedback);
+    }
+
+    @Override
+    public List<Feedback> findAll() {
+        return feedbackRepository.findAllByIsEnabledTrue(SortTools.createdAtDown());
+    }
+
+    @Override
+    public void deleteOneById(Integer id) {
+        if (null == id) return;
+        Feedback feedback = feedbackRepository.findOneByIdAndIsEnabledTrue(id);
+        if (null != feedback) {
+            feedback.setIsEnabled(false);
+            feedbackRepository.save(feedback);
+        }
+    }
+}

+ 128 - 0
src/main/java/cn/minbb/iot/service/impl/LogServiceImpl.java

@@ -0,0 +1,128 @@
+package cn.minbb.iot.service.impl;
+
+import cn.minbb.iot.model.Log;
+import cn.minbb.iot.model.repository.LogRepository;
+import cn.minbb.iot.service.HttpClient;
+import cn.minbb.iot.service.LogService;
+import cn.minbb.iot.util.IPCachePool;
+import cn.minbb.iot.util.IPUtil;
+import com.alibaba.fastjson.JSONObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.util.LinkedMultiValueMap;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+import java.util.List;
+
+@Service
+public class LogServiceImpl implements LogService {
+
+    private LogRepository logRepository;
+    private IPCachePool ipCachePool = IPCachePool.getInstance();
+
+    @Autowired
+    public LogServiceImpl(LogRepository logRepository) {
+        this.logRepository = logRepository;
+    }
+
+    @Override
+    public Log save(Log log) {
+        return logRepository.save(log);
+    }
+
+    @Override
+    public List<Log> findByActionAndDataAndCreatedAtBetween(@NotNull String action, @NotNull String data, Date start, Date end) {
+        if (start == null) {
+            start = new Date(0);
+        }
+        if (end == null) {
+            end = new Date(0);
+        }
+        return logRepository.findByActionAndDataAndCreatedAtBetween(action, data, start, end);
+    }
+
+    @Override
+    public List<Log> findByDataContaining(String data) {
+        return null == data ? null : logRepository.findByDataContaining(data);
+    }
+
+    @Override
+    public void saveViewPage(HttpServletRequest request) {
+        String ip = IPUtil.getIPAddress(request);
+        Log log = new Log(request.getMethod(), request.getRequestURI(), true, "", ip);
+        if (request.getAttribute("intercept") != null) {
+            log.setAction(log.getAction() + " Intercepted");
+            log.setSuccess(false);
+        }
+        saveAddressInLogWithIP(ip, log);
+    }
+
+    @Override
+    public void saveUserAction(String action, String data, Boolean success, HttpServletRequest request) {
+        String ip = IPUtil.getIPAddress(request);
+        saveAddressInLogWithIP(ip, new Log(action, data, success, "", ip));
+    }
+
+    private void saveAddressInLogWithIP(String ip, Log log) {
+        this.getAddressByIP(ip, new GetAddressListener() {
+            @Override
+            public void onFailure(Throwable throwable) {
+                log.setRemark(throwable.toString());
+                logRepository.save(log);
+            }
+
+            @Override
+            public void onSuccess(String address) {
+                log.setRemark(address);
+                logRepository.save(log);
+            }
+        });
+    }
+
+    /**
+     * 通过淘宝 IP 地址库获取 IP 位置
+     * 位置信息格式为:国家 · 地区 · 城市 · 运营商
+     *
+     * @param ip                 IP 地址
+     * @param getAddressListener 获取地址监听器
+     */
+    private void getAddressByIP(String ip, GetAddressListener getAddressListener) {
+        if (ipCachePool.getAddress(ip) == null) {
+            String url = "http://ip.taobao.com/service/getIpInfo.php?ip=" + ip;
+            HttpClient httpClient = new HttpClient();
+            httpClient.asyncClient(url, HttpMethod.GET, new LinkedMultiValueMap<>(), new HttpClient.AsyncClientCallback() {
+                @Override
+                public void onFailure(Throwable throwable) {
+                    getAddressListener.onFailure(throwable);
+                }
+
+                @Override
+                public void onSuccess(ResponseEntity<String> stringResponseEntity) {
+                    String address;
+                    String ipJsonString = stringResponseEntity.getBody();
+                    if (ipJsonString != null) {
+                        JSONObject ipJson = JSONObject.parseObject(ipJsonString).getJSONObject("data");
+                        address = ipJson.getString("country") + " · " + ipJson.getString("region") + " · " + ipJson.getString("city") + " · " + ipJson.getString("isp");
+                    } else {
+                        address = "查询地理位置失败";
+                    }
+                    getAddressListener.onSuccess(address);
+                    // 请求成功 - 缓存至地址池
+                    ipCachePool.putAddress(ip, address);
+                }
+            });
+        } else {
+            getAddressListener.onSuccess(ipCachePool.getAddress(ip));
+        }
+    }
+
+    public interface GetAddressListener {
+        void onFailure(Throwable throwable);
+
+        void onSuccess(String address);
+    }
+}

+ 8 - 0
src/main/java/cn/minbb/iot/service/impl/MessageServiceImpl.java

@@ -0,0 +1,8 @@
+package cn.minbb.iot.service.impl;
+
+import cn.minbb.iot.service.MessageService;
+import org.springframework.stereotype.Service;
+
+@Service
+public class MessageServiceImpl implements MessageService {
+}

+ 42 - 0
src/main/java/cn/minbb/iot/service/impl/UserRoleServiceImpl.java

@@ -0,0 +1,42 @@
+package cn.minbb.iot.service.impl;
+
+import cn.minbb.iot.model.UserRole;
+import cn.minbb.iot.model.repository.UserRoleRepository;
+import cn.minbb.iot.service.UserRoleService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@Service
+public class UserRoleServiceImpl implements UserRoleService {
+
+    private UserRoleRepository userRoleRepository;
+
+    @Autowired
+    public UserRoleServiceImpl(UserRoleRepository userRoleRepository) {
+        this.userRoleRepository = userRoleRepository;
+    }
+
+    @Override
+    public UserRole saveOne(UserRole userRole) {
+        return userRoleRepository.save(userRole);
+    }
+
+    @Override
+    public UserRole findOneByRole(UserRole.Role role) {
+        return null == role ? null : userRoleRepository.findOneByRole(role);
+    }
+
+    @Override
+    public Set<UserRole> findAll() {
+        return new HashSet<>(userRoleRepository.findAll());
+    }
+
+    @Override
+    public Set<UserRole> findAllByRoleSet(Set<UserRole.Role> roleSet) {
+        if (roleSet.isEmpty()) return new HashSet<>();
+        return userRoleRepository.findAllByRoleIn(roleSet);
+    }
+}

+ 38 - 0
src/main/java/cn/minbb/iot/service/impl/UserServiceImpl.java

@@ -1,10 +1,22 @@
 package cn.minbb.iot.service.impl;
 
 import cn.minbb.iot.model.User;
+import cn.minbb.iot.model.UserRole;
 import cn.minbb.iot.model.repository.UserRepository;
 import cn.minbb.iot.service.UserService;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.CredentialsExpiredException;
+import org.springframework.security.authentication.DisabledException;
+import org.springframework.security.authentication.LockedException;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.stereotype.Service;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
 @Service
 public class UserServiceImpl implements UserService {
 
@@ -23,4 +35,30 @@ public class UserServiceImpl implements UserService {
     public User findUserByUsername(String username) {
         return null == username ? null : userRepository.findOneByUsername(username);
     }
+
+    @Override
+    public UserDetails loadUserByUsername(String s) {
+        User user = findUserByUsername(s);
+        if (user == null) {
+            throw new BadCredentialsException("用户不存在");
+        } else {
+            if (!user.isAccountNonExpired()) {
+                throw new BadCredentialsException("账户已过期");
+            } else if (!user.isAccountNonLocked()) {
+                throw new LockedException("账户被锁定");
+            } else if (!user.isCredentialsNonExpired()) {
+                throw new CredentialsExpiredException("凭据已过期");
+            } else if (!user.isEnabled()) {
+                throw new DisabledException("账户被禁用");
+            } else {
+                List<GrantedAuthority> grantedAuthorityList = new ArrayList<>();
+                Set<UserRole> userRoleSet = user.getUserRoleSet();
+                for (UserRole userRole : userRoleSet) {
+                    grantedAuthorityList.add(new SimpleGrantedAuthority("ROLE_" + userRole.getRole().name()));
+                }
+                new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), grantedAuthorityList);
+            }
+        }
+        return user;
+    }
 }

+ 10 - 10
src/main/java/cn/minbb/iot/task/AutoConfig.java

@@ -1,10 +1,7 @@
 package cn.minbb.iot.task;
 
-import cn.minbb.iot.config.Const;
-import cn.minbb.iot.model.DeviceData;
 import cn.minbb.iot.service.MqttGateway;
-import cn.minbb.iot.util.Application;
-import com.alibaba.fastjson.JSONObject;
+import cn.minbb.iot.service.MqttService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.scheduling.annotation.Scheduled;
@@ -18,9 +15,11 @@ public class AutoConfig {
     private Logger logger = LoggerFactory.getLogger(AutoConfig.class);
 
     private MqttGateway mqttGateway;
+    private MqttService mqttService;
 
-    public AutoConfig(MqttGateway mqttGateway) {
+    public AutoConfig(MqttGateway mqttGateway, MqttService mqttService) {
         this.mqttGateway = mqttGateway;
+        this.mqttService = mqttService;
     }
 
     /**
@@ -30,10 +29,11 @@ public class AutoConfig {
     @Scheduled(fixedRate = 3000, initialDelay = 1000)
     public void scheduled() {
         int random1 = 1 + ((int) (new Random().nextFloat() * (10 - 1)));
-        mqttGateway.sendToMqtt(Application.getCurrentStringTime(), Const.MQTT_TOPIC_TIME, 2);
-        int random2 = 1 + ((int) (new Random().nextFloat() * (10 - 1)));
-        mqttGateway.sendToMqtt(JSONObject.toJSONString(
-                new DeviceData("3447.92" + random1 + "00 N", "11338.93" + random2 + "33 E",
-                        Application.getCurrentStringTime())), Const.MQTT_TOPIC_CAR_DATA, 2);
+//        mqttGateway.sendToMqtt(Application.getCurrentStringTime(), Const.MQTT_TOPIC_TIME, 2);
+//        int random2 = 1 + ((int) (new Random().nextFloat() * (10 - 1)));
+//        mqttGateway.sendToMqtt(JSONObject.toJSONString(
+//                new DeviceData("3447.92" + random1 + "00 N", "11338.93" + random2 + "33 E",
+//                        Application.getCurrentStringTime())), Const.MQTT_TOPIC_CAR_DATA, 2);
+//        mqttService.publishSync(new Topic(Const.MQTT_TOPIC_TIME, QoS.AT_LEAST_ONCE), Application.getCurrentStringTime());
     }
 }

+ 56 - 0
src/main/java/cn/minbb/iot/util/IPCachePool.java

@@ -0,0 +1,56 @@
+package cn.minbb.iot.util;
+
+public class IPCachePool {
+
+    private static final long EXPIRED = 600000;
+    private LRUCache<String, IPMessage> ipCache;
+
+    private IPCachePool(int cacheSize) {
+        ipCache = new LRUCache<>(cacheSize);
+    }
+
+    private static class IPCachePoolHolder {
+        private static final IPCachePool IP_CACHE_POOL = new IPCachePool(10);
+    }
+
+    public static synchronized IPCachePool getInstance() {
+        return IPCachePoolHolder.IP_CACHE_POOL;
+    }
+
+    public synchronized String getAddress(String ip) {
+        IPMessage ipMessage = (IPMessage) ipCache.get(ip);
+        if (ipMessage != null) {
+            if (System.currentTimeMillis() - ipMessage.time > EXPIRED) {
+                // 过期
+                remove(ip);
+            } else {
+                // 未过期
+                return ipMessage.address;
+            }
+        }
+        return null;
+    }
+
+    public synchronized void putAddress(String ip, String address) {
+        ipCache.put(ip, new IPMessage(System.currentTimeMillis(), address));
+    }
+
+    public synchronized void remove(String ip) {
+        ipCache.remove(ip);
+    }
+
+    @Override
+    public String toString() {
+        return ipCache.toString();
+    }
+
+    class IPMessage {
+        long time;
+        String address;
+
+        IPMessage(long time, String address) {
+            this.time = time;
+            this.address = address;
+        }
+    }
+}

+ 63 - 0
src/main/java/cn/minbb/iot/util/IPUtil.java

@@ -0,0 +1,63 @@
+package cn.minbb.iot.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletRequest;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+public class IPUtil {
+
+    private static Logger logger = LoggerFactory.getLogger(IPUtil.class);
+
+    private static final String UNKNOWN = "unknown";
+
+    private IPUtil() {
+    }
+
+    public static String getIPAddress(HttpServletRequest request) {
+        String ipAddress = null;
+        try {
+            ipAddress = request.getHeader("x-forwarded-for");
+            ipAddress = request.getHeader("X-Forwarded-For");
+            if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
+                ipAddress = request.getHeader("Proxy-Client-IP");
+            }
+            if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
+                ipAddress = request.getHeader("WL-Proxy-Client-IP");
+            }
+            if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
+                ipAddress = request.getHeader("HTTP_CLIENT_IP");
+            }
+            if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
+                ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR");
+            }
+            if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
+                ipAddress = request.getRemoteAddr();
+                if (ipAddress.equals("127.0.0.1")) {
+                    // 根据网卡取本机配置的 IP
+                    InetAddress inetAddress;
+                    try {
+                        inetAddress = InetAddress.getLocalHost();
+                        ipAddress = inetAddress.getHostAddress();
+                    } catch (UnknownHostException e) {
+                        logger.info("{} - {}", e.getCause(), e.getMessage());
+                    }
+                }
+            }
+            // 对于通过多个代理的情况,第一个 IP 为客户端真实 IP,多个 IP 按照','分割
+            if (ipAddress != null && ipAddress.length() > 15) {
+                // "***.***.***.***".length() = 15
+                int index = ipAddress.indexOf(',');
+                if (index > 0) {
+                    ipAddress = ipAddress.substring(0, index);
+                }
+            }
+        } catch (Exception e) {
+            ipAddress = "";
+            logger.info("{} - {}", e.getCause(), e.getMessage());
+        }
+        return ipAddress;
+    }
+}

+ 123 - 0
src/main/java/cn/minbb/iot/util/LRUCache.java

@@ -0,0 +1,123 @@
+package cn.minbb.iot.util;
+
+import java.util.HashMap;
+
+// 链表 + HashMap 容器实现
+public class LRUCache<K, V> {
+
+    private int cacheCapacity;
+    private HashMap<K, CacheNode> caches;
+    private CacheNode first;
+    private CacheNode last;
+
+    public LRUCache(int size) {
+        this.cacheCapacity = size;
+        caches = new HashMap<>(size);
+    }
+
+    public synchronized void put(K k, V v) {
+        CacheNode node = caches.get(k);
+        if (node == null) {
+            if (caches.size() >= cacheCapacity) {
+                caches.remove(last.key);
+                removeLast();
+            }
+            node = new CacheNode();
+            node.key = k;
+        }
+        node.value = v;
+        moveToFirst(node);
+        caches.put(k, node);
+    }
+
+    public synchronized Object get(K k) {
+        CacheNode node = caches.get(k);
+        if (node == null) {
+            return null;
+        }
+        moveToFirst(node);
+        return node.value;
+    }
+
+    public synchronized Object remove(K k) {
+        CacheNode node = caches.get(k);
+        if (node != null) {
+            if (node.pre != null) {
+                node.pre.next = node.next;
+            }
+            if (node.next != null) {
+                node.next.pre = node.pre;
+            }
+            if (node == first) {
+                first = node.next;
+            }
+            if (node == last) {
+                last = node.pre;
+            }
+        }
+        return caches.remove(k);
+    }
+
+    public synchronized void clear() {
+        first = null;
+        last = null;
+        caches.clear();
+    }
+
+    private void moveToFirst(CacheNode node) {
+        if (first == node) {
+            return;
+        }
+        if (node.next != null) {
+            node.next.pre = node.pre;
+        }
+        if (node.pre != null) {
+            node.pre.next = node.next;
+        }
+        if (node == last) {
+            last = last.pre;
+        }
+        if (first == null || last == null) {
+            first = last = node;
+            return;
+        }
+        node.next = first;
+        first.pre = node;
+        first = node;
+        first.pre = null;
+
+    }
+
+    private void removeLast() {
+        if (last != null) {
+            last = last.pre;
+            if (last == null) {
+                first = null;
+            } else {
+                last.next = null;
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        CacheNode node = first;
+        while (node != null) {
+            sb.append(String.format("%s:%s ", node.key, node.value));
+            node = node.next;
+        }
+        return sb.toString();
+    }
+
+    class CacheNode {
+        CacheNode pre;
+        CacheNode next;
+        Object key;
+        Object value;
+
+        CacheNode() {
+            // 无参构造
+        }
+    }
+}

+ 58 - 0
src/main/java/cn/minbb/iot/util/SortTools.java

@@ -0,0 +1,58 @@
+package cn.minbb.iot.util;
+
+import org.springframework.data.domain.Sort;
+
+public class SortTools {
+
+    private SortTools() {
+    }
+
+    public static Sort idUp() {
+        return new Sort(Sort.Direction.ASC, "id");
+    }
+
+    public static Sort idDown() {
+        return new Sort(Sort.Direction.DESC, "id");
+    }
+
+    public static Sort createdAtUp() {
+        return new Sort(Sort.Direction.ASC, "createdAt");
+    }
+
+    public static Sort createdAtDown() {
+        return new Sort(Sort.Direction.DESC, "createdAt");
+    }
+
+    public static Sort priorityUp() {
+        return new Sort(Sort.Direction.ASC, "priority");
+    }
+
+    public static Sort priorityDown() {
+        return new Sort(Sort.Direction.DESC, "priority");
+    }
+
+    public static Sort basicAscSort(String sort) {
+        return new Sort(Sort.Direction.ASC, sort);
+    }
+
+    public static Sort basicDescSort(String sort) {
+        return new Sort(Sort.Direction.DESC, sort);
+    }
+
+    /**
+     * 基本排序
+     *
+     * @param order 默认降序 - desc
+     * @param sort  默认ID - id
+     * @return 排序规则
+     */
+    public static Sort basicSort(String order, String sort) {
+        if (order == null) {
+            order = "desc";
+        }
+        if (sort == null) {
+            sort = "id";
+        }
+        return new Sort(Sort.Direction.fromString(order), sort);
+    }
+}

+ 3 - 3
src/main/resources/application.properties

@@ -25,11 +25,11 @@ spring.thymeleaf.cache=false
 spring.thymeleaf.encoding=UTF-8
 # MQTT 配置信息
 # MQTT - 用户名
-spring.mqtt.username=yumin
+spring.mqtt.username=
 # MQTT - 密码
-spring.mqtt.password=minbb.cn
+spring.mqtt.password=
 # MQTT - 服务器连接地址,如果有多个,用逗号隔开,如:tcp://127.0.0.1:61613,tcp://192.168.2.133:61613
-spring.mqtt.url=tcp://123.207.151.92:1600
+spring.mqtt.url=tcp://my.minbb.cn:1883
 # MQTT - 连接服务器默认客户端 ID
 spring.mqtt.client.id=IoTServer
 # MQTT - 默认的消息推送主题,实际可在调用接口时指定

File diff suppressed because it is too large
+ 5 - 0
src/main/resources/static/css/bootstrap.min.css


File diff suppressed because it is too large
+ 0 - 0
src/main/resources/static/css/bootstrap.min.css.map


+ 625 - 0
src/main/resources/static/css/demo.css

@@ -0,0 +1,625 @@
+.tim-row {
+  margin-bottom: 20px;
+}
+
+.tim-white-buttons {
+  background-color: #777777;
+}
+
+.typography-line {
+  padding-left: 25%;
+  margin-bottom: 35px;
+  position: relative;
+  display: block;
+  width: 100%;
+}
+
+.typography-line span {
+  bottom: 10px;
+  color: #c0c1c2;
+  display: block;
+  font-weight: 400;
+  font-size: 13px;
+  line-height: 13px;
+  left: 0;
+  margin-left: 20px;
+  position: absolute;
+  width: 260px;
+  text-transform: none;
+}
+
+.tim-row {
+  padding-top: 60px;
+}
+
+.tim-row h3 {
+  margin-top: 0;
+}
+
+.switch {
+  margin-right: 20px;
+}
+
+#navbar-full .navbar {
+  border-radius: 0 !important;
+  margin-bottom: 15px;
+  z-index: 2;
+}
+
+#menu-dropdown .navbar {
+  border-radius: 3px;
+}
+
+#pagination-row .pagination-container {
+  height: 100%;
+  max-height: 100%;
+  display: flex;
+  align-items: center;
+}
+
+/* Nucelo Icons */
+
+#icons-row i.nc-icons {
+  font-size: 30px;
+}
+
+.demo-iconshtml {
+  font-size: 62.5%;
+}
+
+.demo-icons body {
+  font-size: 1.6rem;
+  font-family: sans-serif;
+  color: #333333;
+  background: white;
+}
+
+.demo-icons a {
+  color: #608CEE;
+  text-decoration: none;
+}
+
+.demo-icons header {
+  text-align: center;
+  padding: 100px 0 0;
+}
+
+.demo-icons header h1 {
+  font-size: 2.8rem;
+}
+
+.demo-icons header p {
+  font-size: 1.4rem;
+  margin-top: 1em;
+}
+
+.demo-icons header a:hover {
+  text-decoration: underline;
+}
+
+.demo-icons .nc-icon {
+  font-size: 34px;
+}
+
+.demo-icons section {
+  width: 90%;
+  max-width: 1200px;
+  margin: 50px auto;
+}
+
+.demo-icons section h2 {
+  border-bottom: 1px solid #e2e2e2;
+  padding: 0 0 1em .2em;
+  margin-bottom: 1em;
+}
+
+.demo-icons ul::after {
+  clear: both;
+  content: "";
+  display: table;
+}
+
+.demo-icons ul li {
+  width: 20%;
+  float: left;
+  padding: 16px 0;
+  text-align: center;
+  border-radius: .25em;
+  -webkit-transition: background 0.2s;
+  -moz-transition: background 0.2s;
+  transition: background 0.2s;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  overflow: hidden;
+}
+
+.demo-icons ul li:hover {
+  background: #f4f4f4;
+}
+
+.demo-icons ul p,
+.demo-icons ul em,
+.demo-icons ul input {
+  display: inline-block;
+  font-size: 1rem;
+  color: #999999;
+  -webkit-user-select: auto;
+  -moz-user-select: auto;
+  -ms-user-select: auto;
+  user-select: auto;
+  white-space: nowrap;
+  width: 100%;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  cursor: pointer;
+}
+
+.demo-icons ul p {
+  padding: 20px 0 0;
+  font-size: 12px;
+  margin: 0;
+}
+
+.demo-icons ul p::selection,
+.demo-icons ul em::selection {
+  background: #608CEE;
+  color: #efefef;
+}
+
+.demo-icons ul em {
+  font-size: 12px;
+}
+
+.demo-icons ul em::before {
+  content: '[';
+}
+
+.demo-icons ul em::after {
+  content: ']';
+}
+
+.demo-icons ul input {
+  text-align: center;
+  background: transparent;
+  border: none;
+  box-shadow: none;
+  outline: none;
+  display: none;
+}
+
+.space {
+  height: 130px;
+  display: block;
+}
+
+.space-110 {
+  height: 110px;
+  display: block;
+}
+
+.space-50 {
+  height: 50px;
+  display: block;
+}
+
+.space-70 {
+  height: 70px;
+  display: block;
+}
+
+.navigation-example {
+  background-attachment: scroll;
+}
+
+.navigation-example {
+  background-position: center center;
+  background-size: cover;
+  margin-top: 0;
+  height: 100%;
+}
+
+#notifications {
+  background-color: #FFFFFF;
+  display: block;
+  width: 100%;
+  position: relative;
+}
+
+.tim-note {
+  text-transform: capitalize;
+}
+
+.download-area {
+  margin-top: 30px;
+}
+
+.sharing-area {
+  margin-top: 50px;
+}
+
+.sharing-area .btn {
+  margin-top: 14px;
+}
+
+.upgrade-pro .btn {
+  margin-top: 30px;
+}
+
+#buttons .btn,
+#javascriptComponents .btn {
+  margin: 0 0px 10px;
+}
+
+.space-100 {
+  height: 100px;
+  display: block;
+  width: 100%;
+}
+
+.be-social {
+  padding-bottom: 20px;
+  /*     border-bottom: 1px solid #aaa; */
+  margin: 0 auto 40px;
+}
+
+.txt-white {
+  color: #FFFFFF;
+}
+
+.txt-gray {
+  color: #ddd !important;
+}
+
+.parallax {
+  width: 100%;
+  height: 570px;
+  display: block;
+  background-attachment: fixed;
+  background-repeat: no-repeat;
+  background-size: cover;
+  background-position: center center;
+}
+
+.profile-content {
+  padding-top: 0;
+  position: relative;
+  z-index: 2;
+}
+
+.logo-container .logo {
+  overflow: hidden;
+  border-radius: 50%;
+  border: 1px solid #333333;
+  width: 50px;
+  float: left;
+}
+
+.logo-container .brand {
+  font-size: 16px;
+  color: #FFFFFF;
+  line-height: 18px;
+  float: left;
+  margin-left: 10px;
+  margin-top: 7px;
+  width: 70px;
+  height: 40px;
+  text-align: left;
+}
+
+.logo-container .brand-material {
+  font-size: 18px;
+  margin-top: 15px;
+  height: 25px;
+  width: auto;
+}
+
+.logo-container .logo img {
+  width: 100%;
+}
+
+.navbar-small .logo-container .brand {
+  color: #333333;
+}
+
+.fixed-section {
+  top: 90px;
+  max-height: 80vh;
+  overflow: scroll;
+  position: sticky;
+}
+
+.fixed-section ul {
+  padding: 0;
+}
+
+.fixed-section ul li {
+  list-style: none;
+}
+
+.fixed-section li a {
+  font-size: 14px;
+  padding: 2px;
+  display: block;
+  color: #666666;
+}
+
+.fixed-section li a.active {
+  color: #00bbff;
+}
+
+.fixed-section.float {
+  position: fixed;
+  top: 100px;
+  width: 200px;
+  margin-top: 0;
+}
+
+.parallax .parallax-image {
+  width: 100%;
+  overflow: hidden;
+  position: absolute;
+}
+
+.parallax .parallax-image img {
+  width: 100%;
+}
+
+@media (max-width: 768px) {
+  .parallax .parallax-image {
+    width: 100%;
+    height: 640px;
+    overflow: hidden;
+  }
+  .parallax .parallax-image img {
+    height: 100%;
+    width: auto;
+  }
+}
+
+/*.separator{
+    content: "Separator";
+    color: #FFFFFF;
+    display: block;
+    width: 100%;
+    padding: 20px;
+}
+.separator-line{
+    background-color: #EEE;
+    height: 1px;
+    width: 100%;
+    display: block;
+}
+.separator.separator-gray{
+    background-color: #EEEEEE;
+}*/
+
+.social-buttons-demo .btn {
+  margin-right: 5px;
+  margin-bottom: 7px;
+}
+
+.img-container {
+  width: 100%;
+  overflow: hidden;
+}
+
+.img-container img {
+  width: 100%;
+}
+
+.lightbox img {
+  width: 100%;
+}
+
+.lightbox .modal-content {
+  overflow: hidden;
+}
+
+.lightbox .modal-body {
+  padding: 0;
+}
+
+@media screen and (min-width: 991px) {
+  .lightbox .modal-dialog {
+    width: 960px;
+  }
+}
+
+@media (max-width: 991px) {
+  .fixed-section.affix {
+    position: relative;
+    margin-bottom: 100px;
+  }
+}
+
+@media (max-width: 768px) {
+  .btn,
+  .btn-morphing {
+    margin-bottom: 10px;
+  }
+  .parallax .motto {
+    top: 170px;
+    margin-top: 0;
+    font-size: 60px;
+    width: 270px;
+  }
+}
+
+/*       Loading dots  */
+
+/*      transitions */
+
+.presentation .front,
+.presentation .front:after,
+.presentation .front .btn,
+.logo-container .logo,
+.logo-container .brand {
+  -webkit-transition: all .2s;
+  -moz-transition: all .2s;
+  -o-transition: all .2s;
+  transition: all .2s;
+}
+
+#images h4 {
+  margin-bottom: 30px;
+}
+
+#javascriptComponents {
+  padding-bottom: 0;
+}
+
+/*      layer animation          */
+
+.layers-container {
+  display: block;
+  margin-top: 50px;
+  position: relative;
+}
+
+.layers-container img {
+  position: absolute;
+  width: 100%;
+  height: auto;
+  top: 0;
+  left: 0;
+  text-align: center;
+}
+
+.animate {
+  transition: 1.5s ease-in-out;
+  -moz-transition: 1.5s ease-in-out;
+  -webkit-transition: 1.5s ease-in-out;
+}
+
+.navbar-default.navbar-small .logo-container .brand {
+  color: #333333;
+}
+
+.navbar-transparent.navbar-small .logo-container .brand {
+  color: #FFFFFF;
+}
+
+.navbar-default.navbar-small .logo-container .brand {
+  color: #333333;
+}
+
+.sharing-area {
+  margin-top: 80px;
+}
+
+.sharing-area .btn {
+  margin: 15px 4px 0;
+}
+
+.section-thin,
+.section-notifications {
+  padding: 0;
+}
+
+.section-navbars {
+  padding-top: 0;
+}
+
+.section-tabs {
+  background: #EEEEEE;
+}
+
+.section-pagination {
+  padding-bottom: 0;
+}
+
+.section-download {
+  padding-top: 130px;
+}
+
+.section-download .description {
+  margin-bottom: 60px;
+}
+
+.section-download h4 {
+  margin-bottom: 25px;
+}
+
+.section-examples a {
+  text-decoration: none;
+}
+
+.section-examples a+a {
+  margin-top: 30px;
+}
+
+.section-examples h5 {
+  margin-top: 30px;
+}
+
+.components-page .wrapper>.header,
+.tutorial-page .wrapper>.header {
+  height: 500px;
+  padding-top: 128px;
+  background-size: cover;
+  background-position: center center;
+}
+
+.components-page .title,
+.tutorial-page .title {
+  color: #FFFFFF;
+}
+
+.brand .h1-seo {
+  font-size: 2.8em;
+  text-transform: uppercase;
+  font-weight: 300;
+}
+
+.brand .n-logo {
+  max-width: 100px;
+  margin-bottom: 40px;
+}
+
+.invision-logo {
+  max-width: 70px;
+  top: -2px;
+  position: relative;
+}
+
+.creative-tim-logo {
+  max-width: 140px;
+  top: -2px;
+  position: relative;
+}
+
+.section-javascript .title {
+  margin-bottom: 0;
+}
+
+.navbar .switch-background {
+  display: block;
+}
+
+.navbar-transparent .switch-background {
+  display: none;
+}
+
+.section-signup .col .btn {
+  margin-top: 30px;
+}
+
+#buttons-row .btn {
+  margin-bottom: 10px;
+}
+
+.section-basic {
+  padding-top: 0;
+}
+
+.section-images {
+  padding-bottom: 0;
+}
+
+@media screen and (max-width: 991px) {
+  .section-navbars .navbar-collapse {
+    display: none !important;
+  }
+}

+ 8187 - 0
src/main/resources/static/css/paper-kit.css

@@ -0,0 +1,8187 @@
+/*!
+
+ =========================================================
+ * Paper Kit - v2.2.0
+ =========================================================
+
+ * Product Page: https://www.creative-tim.com/product/paper-kit-2
+ * Copyright 2019 Creative Tim (http://www.creative-tim.com)
+
+ * Designed by www.invisionapp.com Coded by www.creative-tim.com
+
+ =========================================================
+
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ */
+
+/*      light colors - used for select dropdown         */
+
+/* ========================================================================
+ * bootstrap-switch - v3.3.2
+ * http://www.bootstrap-switch.org
+ * ========================================================================
+ * Copyright 2012-2013 Mattia Larentis
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+
+.bootstrap-switch {
+  display: inline-block;
+  direction: ltr;
+  cursor: pointer;
+  border-radius: 30px;
+  border: 0;
+  position: relative;
+  text-align: left;
+  overflow: hidden;
+  margin-bottom: 5px;
+  line-height: 8px;
+  width: 61px !important;
+  height: 26px;
+  outline: none;
+  z-index: 0;
+  margin-right: 1px;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  vertical-align: middle;
+  -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+  transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+}
+
+.bootstrap-switch .bootstrap-switch-container {
+  display: inline-flex;
+  top: 0;
+  height: 26px;
+  border-radius: 4px;
+  -webkit-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+  width: 100px !important;
+}
+
+.bootstrap-switch .bootstrap-switch-handle-on,
+.bootstrap-switch .bootstrap-switch-handle-off,
+.bootstrap-switch .bootstrap-switch-label {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  cursor: pointer;
+  display: inline-block !important;
+  height: 100%;
+  color: #fff;
+  padding: 6px 12px;
+  font-size: 11px;
+  text-indent: -5px;
+  line-height: 15px;
+  -webkit-transition: 0.25s ease-out;
+  transition: 0.25s ease-out;
+}
+
+.bootstrap-switch .bootstrap-switch-handle-on i,
+.bootstrap-switch .bootstrap-switch-handle-off i,
+.bootstrap-switch .bootstrap-switch-label i {
+  font-size: 12px;
+  line-height: 14px;
+}
+
+.bootstrap-switch .bootstrap-switch-handle-on,
+.bootstrap-switch .bootstrap-switch-handle-off {
+  text-align: center;
+  z-index: 1;
+  float: left;
+  width: 50% !important;
+  background-color: #66615B;
+}
+
+.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-primary,
+.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-primary {
+  color: #fff;
+  background: #51cbce;
+}
+
+.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-info,
+.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-info {
+  color: #fff;
+  background: #51bcda;
+}
+
+.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-success,
+.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-success {
+  color: #fff;
+  background: #6bd098;
+}
+
+.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-warning,
+.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-warning {
+  background: #fbc658;
+  color: #fff;
+}
+
+.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-danger,
+.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-danger {
+  color: #fff;
+  background: #f5593d;
+}
+
+.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-default {
+  color: #fff;
+  background: #66615B;
+}
+
+.bootstrap-switch .bootstrap-switch-label {
+  text-align: center;
+  z-index: 100;
+  color: #333333;
+  background: #ffffff;
+  width: 22px !important;
+  height: 22px;
+  margin: 2px -11px;
+  border-radius: 12px;
+  position: relative;
+  float: left;
+  padding: 0;
+  background-color: #FFFFFF;
+  box-shadow: 0 1px 1px #FFFFFF inset, 0 1px 1px rgba(0, 0, 0, 0.25);
+}
+
+.bootstrap-switch .bootstrap-switch-handle-on {
+  border-bottom-left-radius: 3px;
+  border-top-left-radius: 3px;
+}
+
+.bootstrap-switch .bootstrap-switch-handle-off {
+  text-indent: 6px;
+}
+
+.bootstrap-switch input[type='radio'],
+.bootstrap-switch input[type='checkbox'] {
+  position: absolute !important;
+  top: 0;
+  left: 0;
+  opacity: 0;
+  filter: alpha(opacity=0);
+  z-index: -1;
+}
+
+.bootstrap-switch input[type='radio'].form-control,
+.bootstrap-switch input[type='checkbox'].form-control {
+  height: auto;
+}
+
+.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-on,
+.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-off,
+.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-label {
+  padding: 1px 5px;
+  font-size: 12px;
+  line-height: 1.5;
+}
+
+.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-on,
+.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-off,
+.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-label {
+  padding: 5px 10px;
+  font-size: 12px;
+  line-height: 1.5;
+}
+
+.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-on,
+.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-off,
+.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-label {
+  padding: 6px 16px;
+  font-size: 18px;
+  line-height: 1.33;
+}
+
+.bootstrap-switch.bootstrap-switch-disabled,
+.bootstrap-switch.bootstrap-switch-readonly,
+.bootstrap-switch.bootstrap-switch-indeterminate {
+  cursor: default !important;
+}
+
+.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-on,
+.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-on,
+.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-on,
+.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-off,
+.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-off,
+.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-off,
+.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-label,
+.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-label,
+.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-label {
+  opacity: 0.5;
+  filter: alpha(opacity=50);
+  cursor: default !important;
+}
+
+.bootstrap-switch.bootstrap-switch-animate .bootstrap-switch-container {
+  -webkit-transition: margin-left 0.5s;
+  transition: margin-left 0.5s;
+}
+
+.bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-on {
+  border-bottom-left-radius: 0;
+  border-top-left-radius: 0;
+  border-bottom-right-radius: 3px;
+  border-top-right-radius: 3px;
+}
+
+.bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-off {
+  border-bottom-right-radius: 0;
+  border-top-right-radius: 0;
+  border-bottom-left-radius: 3px;
+  border-top-left-radius: 3px;
+}
+
+.bootstrap-switch.bootstrap-switch-on .bootstrap-switch-container {
+  margin-left: -2px !important;
+}
+
+.bootstrap-switch.bootstrap-switch-off .bootstrap-switch-container {
+  margin-left: -37px !important;
+}
+
+.bootstrap-switch.bootstrap-switch-on:hover .bootstrap-switch-label {
+  width: 26px !important;
+  margin: 2px -15px;
+}
+
+.bootstrap-switch.bootstrap-switch-off:hover .bootstrap-switch-label {
+  width: 26px !important;
+  margin: 2px -15px -13px -11px;
+}
+
+.bootstrap-switch.bootstrap-switch-on .bootstrap-switch-handle-off {
+  background-color: #66615B;
+}
+
+.bootstrap-switch.bootstrap-switch-off .bootstrap-switch-handle-on {
+  background-color: #cfcfca;
+}
+
+.bootstrap-switch.bootstrap-switch-on .bootstrap-switch-danger {
+  background-color: #f5593d;
+}
+
+.bootstrap-switch.bootstrap-switch-on .bootstrap-switch-warning {
+  background-color: #fbc658;
+}
+
+.bootstrap-switch.bootstrap-switch-on .bootstrap-switch-success {
+  background-color: #6bd098;
+}
+
+.bootstrap-switch.bootstrap-switch-on .bootstrap-switch-primary {
+  background-color: #51cbce;
+}
+
+.bootstrap-switch.bootstrap-switch-on .bootstrap-switch-info {
+  background-color: #51bcda;
+}
+
+.bootstrap-switch.bootstrap-switch-on .bootstrap-switch-default {
+  background-color: #66615B;
+}
+
+.bootstrap-switch.bootstrap-switch-off .bootstrap-switch-danger,
+.bootstrap-switch.bootstrap-switch-off .bootstrap-switch-primary,
+.bootstrap-switch.bootstrap-switch-off .bootstrap-switch-info,
+.bootstrap-switch.bootstrap-switch-off .bootstrap-switch-warning,
+.bootstrap-switch.bootstrap-switch-off .bootstrap-switch-success {
+  background-color: #cfcfca;
+}
+
+/* Functional styling;
+ * These styles are required for noUiSlider to function.
+ * You don't need to change these rules to apply your design.
+ */
+
+.noUi-target,
+.noUi-target * {
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -ms-touch-action: none;
+  touch-action: none;
+  -ms-user-select: none;
+  -moz-user-select: none;
+  user-select: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+
+.noUi-target {
+  position: relative;
+  direction: ltr;
+}
+
+.noUi-base {
+  width: 100%;
+  height: 100%;
+  position: relative;
+  z-index: 1;
+  /* Fix 401 */
+}
+
+.noUi-connect {
+  position: absolute;
+  right: 0;
+  top: 0;
+  left: 0;
+  bottom: 0;
+}
+
+.noUi-origin {
+  position: absolute;
+  height: 0;
+  width: 0;
+  margin: 0;
+  border-radius: 0;
+  height: 2px;
+  background: #c8c8c8;
+}
+
+.noUi-origin[style^="left: 0"] .noUi-handle {
+  background-color: #fff;
+  border: 2px solid #c8c8c8;
+}
+
+.noUi-origin[style^="left: 0"] .noUi-handle.noUi-active {
+  border-width: 1px;
+}
+
+.noUi-handle {
+  position: relative;
+  z-index: 1;
+}
+
+.noUi-state-tap .noUi-connect,
+.noUi-state-tap .noUi-origin {
+  -webkit-transition: top 0.3s, right 0.3s, bottom 0.3s, left 0.3s;
+  transition: top 0.3s, right 0.3s, bottom 0.3s, left 0.3s;
+}
+
+.noUi-state-drag * {
+  cursor: inherit !important;
+}
+
+/* Painting and performance;
+ * Browsers can paint handles in their own layer.
+ */
+
+.noUi-base,
+.noUi-handle {
+  -webkit-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+}
+
+/* Slider size and handle placement;
+ */
+
+.noUi-horizontal {
+  height: 2px;
+  margin: 15px 0;
+}
+
+.noUi-vertical {
+  width: 18px;
+}
+
+.noUi-vertical .noUi-handle {
+  width: 28px;
+  height: 34px;
+  left: -6px;
+  top: -17px;
+}
+
+/* Styling;
+ */
+
+.noUi-target {
+  background: #c8c8c8;
+  border-radius: 4px;
+}
+
+.noUi-connect {
+  background: #3FB8AF;
+  -webkit-transition: background 450ms;
+  transition: background 450ms;
+}
+
+/* Handles and cursors;
+ */
+
+.noUi-draggable {
+  cursor: w-resize;
+}
+
+.noUi-vertical .noUi-draggable {
+  cursor: n-resize;
+}
+
+.noUi-handle {
+  box-sizing: border-box;
+  width: 14px;
+  height: 14px;
+  left: -10px;
+  top: -6px;
+  cursor: pointer;
+  border-radius: 100%;
+  transition: all 0.2s ease-out;
+  border: 1px solid;
+  background: #FFFFFF;
+}
+
+.noUi-handle.noUi-active {
+  transform: scale3d(1.5, 1.5, 1);
+}
+
+.noUi-vertical .noUi-handle:before,
+.noUi-vertical .noUi-handle:after {
+  width: 14px;
+  height: 1px;
+  left: 6px;
+  top: 14px;
+}
+
+.noUi-vertical .noUi-handle:after {
+  top: 17px;
+}
+
+/* Disabled state;
+ */
+
+[disabled] .noUi-connect {
+  background: #B8B8B8;
+}
+
+[disabled].noUi-target,
+[disabled].noUi-handle,
+[disabled] .noUi-handle {
+  cursor: not-allowed;
+}
+
+.slider {
+  background: #c8c8c8;
+}
+
+.slider .noUi-connect {
+  background-color: #51cbce;
+  border-radius: 4px;
+}
+
+.slider .noUi-handle {
+  border-color: #51cbce;
+}
+
+.slider.slider-info .noUi-connect {
+  background-color: #51bcda;
+}
+
+.slider.slider-info .noUi-handle {
+  border-color: #51bcda;
+}
+
+.slider.slider-success .noUi-connect {
+  background-color: #6bd098;
+}
+
+.slider.slider-success .noUi-handle {
+  border-color: #6bd098;
+}
+
+.slider.slider-warning .noUi-connect {
+  background-color: #fbc658;
+}
+
+.slider.slider-warning .noUi-handle {
+  border-color: #fbc658;
+}
+
+.slider.slider-danger .noUi-connect {
+  background-color: #f5593d;
+}
+
+.slider.slider-danger .noUi-handle {
+  border-color: #f5593d;
+}
+
+/*!
+ * Datetimepicker for Bootstrap 3
+ * ! version : 4.7.14
+ * https://github.com/Eonasdan/bootstrap-datetimepicker/
+ */
+
+.sr-only,
+.bootstrap-datetimepicker-widget .btn[data-action="incrementHours"]::after,
+.bootstrap-datetimepicker-widget .btn[data-action="incrementMinutes"]::after,
+.bootstrap-datetimepicker-widget .btn[data-action="decrementHours"]::after,
+.bootstrap-datetimepicker-widget .btn[data-action="decrementMinutes"]::after,
+.bootstrap-datetimepicker-widget .btn[data-action="showHours"]::after,
+.bootstrap-datetimepicker-widget .btn[data-action="showMinutes"]::after,
+.bootstrap-datetimepicker-widget .btn[data-action="togglePeriod"]::after,
+.bootstrap-datetimepicker-widget .btn[data-action="clear"]::after,
+.bootstrap-datetimepicker-widget .btn[data-action="today"]::after,
+.bootstrap-datetimepicker-widget .picker-switch::after,
+.bootstrap-datetimepicker-widget table th.prev::after,
+.bootstrap-datetimepicker-widget table th.next::after {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  margin: -1px;
+  padding: 0;
+  overflow: hidden;
+  clip: rect(0, 0, 0, 0);
+  border: 0;
+}
+
+.bootstrap-datetimepicker-widget {
+  list-style: none;
+}
+
+.bootstrap-datetimepicker-widget a .btn:hover {
+  background-color: transparent;
+}
+
+.bootstrap-datetimepicker-widget.dropdown-menu {
+  padding: 4px;
+  width: 16em;
+}
+
+@media (min-width: 768px) {
+  .bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
+    width: 38em;
+  }
+}
+
+@media (min-width: 992px) {
+  .bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
+    width: 38em;
+  }
+}
+
+@media (min-width: 1200px) {
+  .bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
+    width: 38em;
+  }
+}
+
+.bootstrap-datetimepicker-widget.dropdown-menu.bottom:before {
+  border-bottom: 11px solid #F1EAE0;
+  border-left: 11px solid transparent;
+  border-right: 11px solid transparent;
+  content: "";
+  display: inline-block;
+  position: absolute;
+  right: 12px;
+  left: auto;
+  top: -12px;
+}
+
+.bootstrap-datetimepicker-widget.dropdown-menu.bottom:after {
+  border-bottom: 11px solid #FFFFFF;
+  border-left: 11px solid transparent;
+  border-right: 11px solid transparent;
+  content: "";
+  display: inline-block;
+  position: absolute;
+  right: 12px;
+  left: auto;
+  top: -11px;
+}
+
+.bootstrap-datetimepicker-widget.dropdown-menu.top {
+  margin-top: auto;
+  margin-bottom: -20px;
+}
+
+.bootstrap-datetimepicker-widget.dropdown-menu.top.open {
+  margin-top: auto;
+  margin-bottom: 5px;
+}
+
+.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:before {
+  left: auto;
+  right: 6px;
+}
+
+.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:after {
+  left: auto;
+  right: 7px;
+}
+
+.bootstrap-datetimepicker-widget .list-unstyled {
+  margin: 0;
+}
+
+.bootstrap-datetimepicker-widget a[data-action] {
+  padding: 6px 0;
+  border-width: 0;
+  color: #66615B;
+  background-color: transparent;
+}
+
+.bootstrap-datetimepicker-widget a[data-action="togglePicker"],
+.bootstrap-datetimepicker-widget a[data-action="togglePicker"]:hover {
+  color: #429cb6 !important;
+}
+
+.bootstrap-datetimepicker-widget a[data-action]:hover {
+  background-color: transparent;
+  color: rgba(255, 255, 255, 0.85);
+}
+
+.bootstrap-datetimepicker-widget a[data-action]:active {
+  box-shadow: none;
+}
+
+.bootstrap-datetimepicker-widget .timepicker-hour,
+.bootstrap-datetimepicker-widget .timepicker-minute,
+.bootstrap-datetimepicker-widget .timepicker-second {
+  width: 40px;
+  height: 40px;
+  line-height: 40px;
+  font-weight: 300;
+  font-size: 1.5em;
+  margin: 3px;
+  border-radius: 50%;
+}
+
+.bootstrap-datetimepicker-widget button[data-action] {
+  width: 38px;
+  height: 38px;
+  padding: 0;
+}
+
+.bootstrap-datetimepicker-widget .btn[data-action="incrementHours"]::after {
+  content: "Increment Hours";
+}
+
+.bootstrap-datetimepicker-widget .btn[data-action="incrementMinutes"]::after {
+  content: "Increment Minutes";
+}
+
+.bootstrap-datetimepicker-widget .btn[data-action="decrementHours"]::after {
+  content: "Decrement Hours";
+}
+
+.bootstrap-datetimepicker-widget .btn[data-action="decrementMinutes"]::after {
+  content: "Decrement Minutes";
+}
+
+.bootstrap-datetimepicker-widget .btn[data-action="showHours"]::after {
+  content: "Show Hours";
+}
+
+.bootstrap-datetimepicker-widget .btn[data-action="showMinutes"]::after {
+  content: "Show Minutes";
+}
+
+.bootstrap-datetimepicker-widget .btn[data-action="togglePeriod"]::after {
+  content: "Toggle AM/PM";
+}
+
+.bootstrap-datetimepicker-widget .btn[data-action="clear"]::after {
+  content: "Clear the picker";
+}
+
+.bootstrap-datetimepicker-widget .btn[data-action="today"]::after {
+  content: "Set the date to today";
+}
+
+.bootstrap-datetimepicker-widget .picker-switch {
+  text-align: center;
+  border-radius: 4px;
+}
+
+.bootstrap-datetimepicker-widget .picker-switch::after {
+  content: "Toggle Date and Time Screens";
+}
+
+.bootstrap-datetimepicker-widget .picker-switch td {
+  padding: 0;
+  margin: 0;
+  height: auto;
+  width: auto;
+  line-height: inherit;
+}
+
+.bootstrap-datetimepicker-widget .picker-switch td span {
+  line-height: 2.5;
+  height: 2.5em;
+  width: 100%;
+  border-radius: 4px;
+  margin: 2px 0px !important;
+}
+
+.bootstrap-datetimepicker-widget table {
+  width: 100%;
+  margin: 0;
+}
+
+.bootstrap-datetimepicker-widget table td>div,
+.bootstrap-datetimepicker-widget table th>div {
+  text-align: center;
+}
+
+.bootstrap-datetimepicker-widget table th {
+  height: 20px;
+  line-height: 20px;
+  width: 20px;
+}
+
+.bootstrap-datetimepicker-widget table th.picker-switch {
+  width: 145px;
+}
+
+.bootstrap-datetimepicker-widget table th.disabled,
+.bootstrap-datetimepicker-widget table th.disabled:hover {
+  background: none;
+  color: #cfcfca;
+  cursor: not-allowed;
+}
+
+.bootstrap-datetimepicker-widget table th.prev span,
+.bootstrap-datetimepicker-widget table th.next span {
+  border-radius: 4px;
+  height: 27px;
+  width: 27px;
+  line-height: 28px;
+  font-size: 12px;
+  border-radius: 50%;
+  text-align: center;
+}
+
+.bootstrap-datetimepicker-widget table th.prev::after {
+  content: "Previous Month";
+}
+
+.bootstrap-datetimepicker-widget table th.next::after {
+  content: "Next Month";
+}
+
+.bootstrap-datetimepicker-widget table th.dow {
+  text-align: center;
+  border-bottom: 1px solid #E3E3E3;
+  font-size: 12px;
+  text-transform: uppercase;
+  color: #9A9A9A;
+  font-weight: 400;
+  padding-bottom: 5px;
+  padding-top: 10px;
+}
+
+.bootstrap-datetimepicker-widget table thead tr:first-child th {
+  cursor: pointer;
+}
+
+.bootstrap-datetimepicker-widget table thead tr:first-child th:hover span,
+.bootstrap-datetimepicker-widget table thead tr:first-child th.picker-switch:hover {
+  background: #E3E3E3;
+}
+
+.bootstrap-datetimepicker-widget table td>div {
+  border-radius: 4px;
+  height: 54px;
+  line-height: 54px;
+  width: 54px;
+  text-align: center;
+}
+
+.bootstrap-datetimepicker-widget table td.cw>div {
+  font-size: .8em;
+  height: 20px;
+  line-height: 20px;
+  color: #cfcfca;
+}
+
+.bootstrap-datetimepicker-widget table td.day>div {
+  height: 30px;
+  line-height: 31px;
+  width: 30px;
+  text-align: center;
+  padding: 0px;
+  border-radius: 50%;
+  margin: 0 auto;
+  z-index: -1;
+  position: relative;
+}
+
+.table-condensed .day:hover div {
+  -webkit-transition: all 150ms linear;
+  -moz-transition: all 150ms linear;
+  -o-transition: all 150ms linear;
+  -ms-transition: all 150ms linear;
+  transition: all 150ms linear;
+}
+
+.bootstrap-datetimepicker-widget table td.minute>div,
+.bootstrap-datetimepicker-widget table td.hour>div {
+  border-radius: 50%;
+}
+
+.bootstrap-datetimepicker-widget table td.day:hover>div,
+.bootstrap-datetimepicker-widget table td.hour:hover>div,
+.bootstrap-datetimepicker-widget table td.minute:hover>div,
+.bootstrap-datetimepicker-widget table td.second:hover>div {
+  background: #E3E3E3;
+  cursor: pointer;
+}
+
+.bootstrap-datetimepicker-widget table td.old>div,
+.bootstrap-datetimepicker-widget table td.new>div {
+  color: #cfcfca;
+}
+
+.bootstrap-datetimepicker-widget table td.active>div,
+.bootstrap-datetimepicker-widget table td.active:hover>div {
+  background-color: #68B3C8;
+  color: #FFFFFF;
+}
+
+.bootstrap-datetimepicker-widget table td.active.today:before>div {
+  border-bottom-color: #FFFFFF;
+}
+
+.bootstrap-datetimepicker-widget table td.disabled>div,
+.bootstrap-datetimepicker-widget table td.disabled:hover>div {
+  background: none;
+  color: #cfcfca;
+  cursor: not-allowed;
+}
+
+.bootstrap-datetimepicker-widget table td span {
+  display: inline-block;
+  width: 40px;
+  height: 40px;
+  line-height: 40px;
+  margin: 3px 3px;
+  cursor: pointer;
+  border-radius: 50%;
+  text-align: center;
+}
+
+.bootstrap-datetimepicker-widget table td span:hover {
+  background: #E3E3E3;
+}
+
+.bootstrap-datetimepicker-widget table td span.active {
+  background-color: #68B3C8;
+  color: #FFFFFF;
+}
+
+.bootstrap-datetimepicker-widget table td span.old {
+  color: #cfcfca;
+}
+
+.bootstrap-datetimepicker-widget table td span.disabled,
+.bootstrap-datetimepicker-widget table td span.disabled:hover {
+  background: none;
+  color: #cfcfca;
+  cursor: not-allowed;
+}
+
+.bootstrap-datetimepicker-widget .timepicker-picker span,
+.bootstrap-datetimepicker-widget .timepicker-hours span,
+.bootstrap-datetimepicker-widget .timepicker-minutes span {
+  border-radius: 50% !important;
+}
+
+.bootstrap-datetimepicker-widget.usetwentyfour td.hour {
+  height: 27px;
+  line-height: 27px;
+}
+
+.input-group.date .input-group-addon {
+  cursor: pointer;
+}
+
+.table-condensed>tbody>tr>td,
+.table-condensed>tbody>tr>th,
+.table-condensed>tfoot>tr>td,
+.table-condensed>tfoot>tr>th,
+.table-condensed>thead>tr>td,
+.table-condensed>thead>tr>th {
+  padding: 1px;
+  text-align: center;
+  z-index: 1;
+  cursor: pointer;
+}
+
+.bootstrap-datetimepicker-widget {
+  opacity: 0;
+  -webkit-transform: translate3d(0px, -10px, 0px);
+  -moz-transform: translate3d(0, -10px, 0);
+  -o-transform: translate3d(0, -10px, 0);
+  -ms-transform: translate3d(0, -10px, 0);
+  transform: translate3d(0px, -10px, 0px);
+  -webkit-box-shadow: 0 2px rgba(17, 16, 15, 0.1), 0 2px 10px rgba(17, 16, 15, 0.1);
+  box-shadow: 0 2px rgba(17, 16, 15, 0.1), 0 2px 10px rgba(17, 16, 15, 0.1);
+}
+
+.bootstrap-datetimepicker-widget.top {
+  -webkit-transform: translate3d(0px, 0px, 0px);
+  -moz-transform: translate3d(0, 0px, 0);
+  -o-transform: translate3d(0, 0px, 0);
+  -ms-transform: translate3d(0, 0px, 0);
+  transform: translate3d(0px, 0px, 0px);
+}
+
+.bootstrap-datetimepicker-widget.open {
+  opacity: 1;
+  -webkit-transform: translate3d(0, 5px, 0);
+  -moz-transform: translate3d(0, 5px, 0);
+  -o-transform: translate3d(0, 5px, 0);
+  -ms-transform: translate3d(0, 5px, 0);
+  transform: translate3d(0, 5px, 0);
+  transition: transform 0.5s cubic-bezier(0.215, 0.61, 0.355, 1) 0s;
+}
+
+.bootstrap-datetimepicker-widget.open.top {
+  -webkit-transform: translate3d(0, -10px, 0);
+  -moz-transform: translate3d(0, -10px, 0);
+  -o-transform: translate3d(0, -10px, 0);
+  -ms-transform: translate3d(0, -10px, 0);
+  transform: translate3d(0, -10px, 0);
+}
+
+.bootstrap-datetimepicker-widget.open.top:before {
+  border-top: 11px solid #DCD9D1;
+  border-left: 11px solid transparent;
+  border-right: 11px solid transparent;
+  content: "";
+  display: inline-block;
+  position: absolute;
+  right: 12px;
+  bottom: -12px;
+}
+
+.bootstrap-datetimepicker-widget.open.top:after {
+  border-top: 11px solid #FFFFFF;
+  border-left: 11px solid transparent;
+  border-right: 11px solid transparent;
+  content: "";
+  display: inline-block;
+  position: absolute;
+  right: 12px;
+  bottom: -11px;
+}
+
+.btn {
+  box-sizing: border-box;
+  border-width: 2px;
+  font-size: 12px;
+  font-weight: 600;
+  padding: 0.5rem 18px;
+  line-height: 1.75;
+  cursor: pointer;
+  text-transform: uppercase;
+  background-color: #66615B;
+  border-color: #66615B;
+  color: #FFFFFF;
+  opacity: 1;
+  filter: alpha(opacity=100);
+  -webkit-transition: all 150ms linear;
+  -moz-transition: all 150ms linear;
+  -o-transition: all 150ms linear;
+  -ms-transition: all 150ms linear;
+  transition: all 150ms linear;
+}
+
+.btn.btn-border,
+.btn.btn-link {
+  background-color: transparent;
+}
+
+.btn:hover,
+.btn:focus,
+.btn:active,
+.btn.active,
+.btn:active:focus,
+.btn:active:hover,
+.btn.active:focus,
+.btn:not(:disabled):not(.disabled):active:focus,
+.btn:not(:disabled):not(.disabled):active,
+.btn:not(:disabled):not(.disabled).active,
+.btn:not(:disabled):not(.disabled).active:focus,
+.show>.btn.dropdown-toggle {
+  background-color: #403D39;
+  color: #FFFFFF;
+  border-color: #403D39;
+  box-shadow: none;
+}
+
+.btn .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn.disabled,
+.btn.disabled:hover,
+.btn.disabled:focus,
+.btn.disabled.focus,
+.btn.disabled:active,
+.btn.disabled.active,
+.btn:disabled,
+.btn:disabled:hover,
+.btn:disabled:focus,
+.btn:disabled.focus,
+.btn:disabled:active,
+.btn:disabled.active,
+.btn[disabled],
+.btn[disabled]:hover,
+.btn[disabled]:focus,
+.btn[disabled].focus,
+.btn[disabled]:active,
+.btn[disabled].active,
+fieldset[disabled] .btn,
+fieldset[disabled] .btn:hover,
+fieldset[disabled] .btn:focus,
+fieldset[disabled] .btn.focus,
+fieldset[disabled] .btn:active,
+fieldset[disabled] .btn.active {
+  background-color: #403D39;
+  border-color: #403D39;
+}
+
+.btn.btn-link {
+  color: #66615B;
+}
+
+.btn.btn-link:hover,
+.btn.btn-link:focus,
+.btn.btn-link:active,
+.btn.btn-link.active,
+.btn.btn-link:focus:active,
+.open>.btn.btn-link.dropdown-toggle {
+  background-color: transparent !important;
+  color: #403D39 !important;
+}
+
+.btn.btn-link .caret {
+  border-top-color: #66615B;
+}
+
+.btn .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn:hover,
+.btn:focus {
+  outline: 0 !important;
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
+
+.btn:active,
+.btn.active,
+.open>.btn.dropdown-toggle {
+  -webkit-box-shadow: none;
+  box-shadow: none;
+  outline: 0 !important;
+}
+
+.btn[class*="btn-outline-"] {
+  background-image: none;
+  background-color: transparent;
+}
+
+.btn .nc-icon {
+  position: relative;
+  top: 2px;
+}
+
+.btn-just-icon {
+  border-radius: 50px;
+  height: 40px;
+  width: 40px;
+  min-width: 40px;
+  padding: 8px;
+}
+
+.btn-just-icon.btn-sm {
+  padding: 4px !important;
+}
+
+.btn-just-icon i {
+  font-size: 16px;
+  padding: 2px 0px;
+}
+
+.btn-group .btn+.btn,
+.btn-group .btn+.btn-group,
+.btn-group .btn-group+.btn,
+.btn-group .btn-group+.btn-group {
+  margin-left: -2px;
+}
+
+.btn-primary {
+  background-color: #51cbce;
+  border-color: #51cbce;
+  color: #FFFFFF;
+  opacity: 1;
+  filter: alpha(opacity=100);
+}
+
+.btn-primary:hover,
+.btn-primary:focus,
+.btn-primary:active,
+.btn-primary.active,
+.btn-primary:active:focus,
+.btn-primary:active:hover,
+.btn-primary.active:focus,
+.btn-primary:not(:disabled):not(.disabled):active:focus,
+.btn-primary:not(:disabled):not(.disabled):active,
+.btn-primary:not(:disabled):not(.disabled).active,
+.btn-primary:not(:disabled):not(.disabled).active:focus,
+.show>.btn-primary.dropdown-toggle {
+  background-color: #34b5b8;
+  color: #FFFFFF;
+  border-color: #34b5b8;
+  box-shadow: none;
+}
+
+.btn-primary .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-primary.disabled,
+.btn-primary.disabled:hover,
+.btn-primary.disabled:focus,
+.btn-primary.disabled.focus,
+.btn-primary.disabled:active,
+.btn-primary.disabled.active,
+.btn-primary:disabled,
+.btn-primary:disabled:hover,
+.btn-primary:disabled:focus,
+.btn-primary:disabled.focus,
+.btn-primary:disabled:active,
+.btn-primary:disabled.active,
+.btn-primary[disabled],
+.btn-primary[disabled]:hover,
+.btn-primary[disabled]:focus,
+.btn-primary[disabled].focus,
+.btn-primary[disabled]:active,
+.btn-primary[disabled].active,
+fieldset[disabled] .btn-primary,
+fieldset[disabled] .btn-primary:hover,
+fieldset[disabled] .btn-primary:focus,
+fieldset[disabled] .btn-primary.focus,
+fieldset[disabled] .btn-primary:active,
+fieldset[disabled] .btn-primary.active {
+  background-color: #34b5b8;
+  border-color: #34b5b8;
+}
+
+.btn-primary.btn-link {
+  color: #51cbce;
+}
+
+.btn-primary.btn-link:hover,
+.btn-primary.btn-link:focus,
+.btn-primary.btn-link:active,
+.btn-primary.btn-link.active,
+.btn-primary.btn-link:focus:active,
+.open>.btn-primary.btn-link.dropdown-toggle {
+  background-color: transparent !important;
+  color: #34b5b8 !important;
+}
+
+.btn-primary.btn-link .caret {
+  border-top-color: #51cbce;
+}
+
+.btn-primary .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-success {
+  background-color: #6bd098;
+  border-color: #6bd098;
+  color: #FFFFFF;
+  opacity: 1;
+  filter: alpha(opacity=100);
+}
+
+.btn-success:hover,
+.btn-success:focus,
+.btn-success:active,
+.btn-success.active,
+.btn-success:active:focus,
+.btn-success:active:hover,
+.btn-success.active:focus,
+.btn-success:not(:disabled):not(.disabled):active:focus,
+.btn-success:not(:disabled):not(.disabled):active,
+.btn-success:not(:disabled):not(.disabled).active,
+.btn-success:not(:disabled):not(.disabled).active:focus,
+.show>.btn-success.dropdown-toggle {
+  background-color: #44c47d;
+  color: #FFFFFF;
+  border-color: #44c47d;
+  box-shadow: none;
+}
+
+.btn-success .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-success.disabled,
+.btn-success.disabled:hover,
+.btn-success.disabled:focus,
+.btn-success.disabled.focus,
+.btn-success.disabled:active,
+.btn-success.disabled.active,
+.btn-success:disabled,
+.btn-success:disabled:hover,
+.btn-success:disabled:focus,
+.btn-success:disabled.focus,
+.btn-success:disabled:active,
+.btn-success:disabled.active,
+.btn-success[disabled],
+.btn-success[disabled]:hover,
+.btn-success[disabled]:focus,
+.btn-success[disabled].focus,
+.btn-success[disabled]:active,
+.btn-success[disabled].active,
+fieldset[disabled] .btn-success,
+fieldset[disabled] .btn-success:hover,
+fieldset[disabled] .btn-success:focus,
+fieldset[disabled] .btn-success.focus,
+fieldset[disabled] .btn-success:active,
+fieldset[disabled] .btn-success.active {
+  background-color: #44c47d;
+  border-color: #44c47d;
+}
+
+.btn-success.btn-link {
+  color: #6bd098;
+}
+
+.btn-success.btn-link:hover,
+.btn-success.btn-link:focus,
+.btn-success.btn-link:active,
+.btn-success.btn-link.active,
+.btn-success.btn-link:focus:active,
+.open>.btn-success.btn-link.dropdown-toggle {
+  background-color: transparent !important;
+  color: #44c47d !important;
+}
+
+.btn-success.btn-link .caret {
+  border-top-color: #6bd098;
+}
+
+.btn-success .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-info {
+  background-color: #51bcda;
+  border-color: #51bcda;
+  color: #FFFFFF;
+  opacity: 1;
+  filter: alpha(opacity=100);
+}
+
+.btn-info:hover,
+.btn-info:focus,
+.btn-info:active,
+.btn-info.active,
+.btn-info:active:focus,
+.btn-info:active:hover,
+.btn-info.active:focus,
+.btn-info:not(:disabled):not(.disabled):active:focus,
+.btn-info:not(:disabled):not(.disabled):active,
+.btn-info:not(:disabled):not(.disabled).active,
+.btn-info:not(:disabled):not(.disabled).active:focus,
+.show>.btn-info.dropdown-toggle {
+  background-color: #2ba9cd;
+  color: #FFFFFF;
+  border-color: #2ba9cd;
+  box-shadow: none;
+}
+
+.btn-info .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-info.disabled,
+.btn-info.disabled:hover,
+.btn-info.disabled:focus,
+.btn-info.disabled.focus,
+.btn-info.disabled:active,
+.btn-info.disabled.active,
+.btn-info:disabled,
+.btn-info:disabled:hover,
+.btn-info:disabled:focus,
+.btn-info:disabled.focus,
+.btn-info:disabled:active,
+.btn-info:disabled.active,
+.btn-info[disabled],
+.btn-info[disabled]:hover,
+.btn-info[disabled]:focus,
+.btn-info[disabled].focus,
+.btn-info[disabled]:active,
+.btn-info[disabled].active,
+fieldset[disabled] .btn-info,
+fieldset[disabled] .btn-info:hover,
+fieldset[disabled] .btn-info:focus,
+fieldset[disabled] .btn-info.focus,
+fieldset[disabled] .btn-info:active,
+fieldset[disabled] .btn-info.active {
+  background-color: #2ba9cd;
+  border-color: #2ba9cd;
+}
+
+.btn-info.btn-link {
+  color: #51bcda;
+}
+
+.btn-info.btn-link:hover,
+.btn-info.btn-link:focus,
+.btn-info.btn-link:active,
+.btn-info.btn-link.active,
+.btn-info.btn-link:focus:active,
+.open>.btn-info.btn-link.dropdown-toggle {
+  background-color: transparent !important;
+  color: #2ba9cd !important;
+}
+
+.btn-info.btn-link .caret {
+  border-top-color: #51bcda;
+}
+
+.btn-info .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-warning {
+  background-color: #fbc658;
+  border-color: #fbc658;
+  color: #FFFFFF;
+  opacity: 1;
+  filter: alpha(opacity=100);
+}
+
+.btn-warning:hover,
+.btn-warning:focus,
+.btn-warning:active,
+.btn-warning.active,
+.btn-warning:active:focus,
+.btn-warning:active:hover,
+.btn-warning.active:focus,
+.btn-warning:not(:disabled):not(.disabled):active:focus,
+.btn-warning:not(:disabled):not(.disabled):active,
+.btn-warning:not(:disabled):not(.disabled).active,
+.btn-warning:not(:disabled):not(.disabled).active:focus,
+.show>.btn-warning.dropdown-toggle {
+  background-color: #fab526;
+  color: #FFFFFF;
+  border-color: #fab526;
+  box-shadow: none;
+}
+
+.btn-warning .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-warning.disabled,
+.btn-warning.disabled:hover,
+.btn-warning.disabled:focus,
+.btn-warning.disabled.focus,
+.btn-warning.disabled:active,
+.btn-warning.disabled.active,
+.btn-warning:disabled,
+.btn-warning:disabled:hover,
+.btn-warning:disabled:focus,
+.btn-warning:disabled.focus,
+.btn-warning:disabled:active,
+.btn-warning:disabled.active,
+.btn-warning[disabled],
+.btn-warning[disabled]:hover,
+.btn-warning[disabled]:focus,
+.btn-warning[disabled].focus,
+.btn-warning[disabled]:active,
+.btn-warning[disabled].active,
+fieldset[disabled] .btn-warning,
+fieldset[disabled] .btn-warning:hover,
+fieldset[disabled] .btn-warning:focus,
+fieldset[disabled] .btn-warning.focus,
+fieldset[disabled] .btn-warning:active,
+fieldset[disabled] .btn-warning.active {
+  background-color: #fab526;
+  border-color: #fab526;
+}
+
+.btn-warning.btn-link {
+  color: #fbc658;
+}
+
+.btn-warning.btn-link:hover,
+.btn-warning.btn-link:focus,
+.btn-warning.btn-link:active,
+.btn-warning.btn-link.active,
+.btn-warning.btn-link:focus:active,
+.open>.btn-warning.btn-link.dropdown-toggle {
+  background-color: transparent !important;
+  color: #fab526 !important;
+}
+
+.btn-warning.btn-link .caret {
+  border-top-color: #fbc658;
+}
+
+.btn-warning .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-danger {
+  background-color: #f5593d;
+  border-color: #f5593d;
+  color: #FFFFFF;
+  opacity: 1;
+  filter: alpha(opacity=100);
+}
+
+.btn-danger:hover,
+.btn-danger:focus,
+.btn-danger:active,
+.btn-danger.active,
+.btn-danger:active:focus,
+.btn-danger:active:hover,
+.btn-danger.active:focus,
+.btn-danger:not(:disabled):not(.disabled):active:focus,
+.btn-danger:not(:disabled):not(.disabled):active,
+.btn-danger:not(:disabled):not(.disabled).active,
+.btn-danger:not(:disabled):not(.disabled).active:focus,
+.show>.btn-danger.dropdown-toggle {
+  background-color: #f33816;
+  color: #FFFFFF;
+  border-color: #f33816;
+  box-shadow: none;
+}
+
+.btn-danger .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-danger.disabled,
+.btn-danger.disabled:hover,
+.btn-danger.disabled:focus,
+.btn-danger.disabled.focus,
+.btn-danger.disabled:active,
+.btn-danger.disabled.active,
+.btn-danger:disabled,
+.btn-danger:disabled:hover,
+.btn-danger:disabled:focus,
+.btn-danger:disabled.focus,
+.btn-danger:disabled:active,
+.btn-danger:disabled.active,
+.btn-danger[disabled],
+.btn-danger[disabled]:hover,
+.btn-danger[disabled]:focus,
+.btn-danger[disabled].focus,
+.btn-danger[disabled]:active,
+.btn-danger[disabled].active,
+fieldset[disabled] .btn-danger,
+fieldset[disabled] .btn-danger:hover,
+fieldset[disabled] .btn-danger:focus,
+fieldset[disabled] .btn-danger.focus,
+fieldset[disabled] .btn-danger:active,
+fieldset[disabled] .btn-danger.active {
+  background-color: #f33816;
+  border-color: #f33816;
+}
+
+.btn-danger.btn-link {
+  color: #f5593d;
+}
+
+.btn-danger.btn-link:hover,
+.btn-danger.btn-link:focus,
+.btn-danger.btn-link:active,
+.btn-danger.btn-link.active,
+.btn-danger.btn-link:focus:active,
+.open>.btn-danger.btn-link.dropdown-toggle {
+  background-color: transparent !important;
+  color: #f33816 !important;
+}
+
+.btn-danger.btn-link .caret {
+  border-top-color: #f5593d;
+}
+
+.btn-danger .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-neutral {
+  background-color: #FFFFFF;
+  border-color: #FFFFFF;
+  color: #FFFFFF;
+  opacity: 1;
+  filter: alpha(opacity=100);
+}
+
+.btn-neutral:hover,
+.btn-neutral:focus,
+.btn-neutral:active,
+.btn-neutral.active,
+.btn-neutral:active:focus,
+.btn-neutral:active:hover,
+.btn-neutral.active:focus,
+.btn-neutral:not(:disabled):not(.disabled):active:focus,
+.btn-neutral:not(:disabled):not(.disabled):active,
+.btn-neutral:not(:disabled):not(.disabled).active,
+.btn-neutral:not(:disabled):not(.disabled).active:focus,
+.show>.btn-neutral.dropdown-toggle {
+  background-color: #403D39;
+  color: #FFFFFF;
+  border-color: #403D39;
+  box-shadow: none;
+}
+
+.btn-neutral .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-neutral.disabled,
+.btn-neutral.disabled:hover,
+.btn-neutral.disabled:focus,
+.btn-neutral.disabled.focus,
+.btn-neutral.disabled:active,
+.btn-neutral.disabled.active,
+.btn-neutral:disabled,
+.btn-neutral:disabled:hover,
+.btn-neutral:disabled:focus,
+.btn-neutral:disabled.focus,
+.btn-neutral:disabled:active,
+.btn-neutral:disabled.active,
+.btn-neutral[disabled],
+.btn-neutral[disabled]:hover,
+.btn-neutral[disabled]:focus,
+.btn-neutral[disabled].focus,
+.btn-neutral[disabled]:active,
+.btn-neutral[disabled].active,
+fieldset[disabled] .btn-neutral,
+fieldset[disabled] .btn-neutral:hover,
+fieldset[disabled] .btn-neutral:focus,
+fieldset[disabled] .btn-neutral.focus,
+fieldset[disabled] .btn-neutral:active,
+fieldset[disabled] .btn-neutral.active {
+  background-color: #403D39;
+  border-color: #403D39;
+}
+
+.btn-neutral.btn-link {
+  color: #FFFFFF;
+}
+
+.btn-neutral.btn-link:hover,
+.btn-neutral.btn-link:focus,
+.btn-neutral.btn-link:active,
+.btn-neutral.btn-link.active,
+.btn-neutral.btn-link:focus:active,
+.open>.btn-neutral.btn-link.dropdown-toggle {
+  background-color: transparent !important;
+  color: #403D39 !important;
+}
+
+.btn-neutral.btn-link .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-neutral .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-outline-default {
+  border-color: #66615B;
+  color: #66615B;
+  opacity: 1;
+  filter: alpha(opacity=100);
+}
+
+.btn-outline-default:hover,
+.btn-outline-default:focus,
+.btn-outline-default:active,
+.btn-outline-default.active,
+.btn-outline-default:active:focus,
+.btn-outline-default:active:hover,
+.btn-outline-default.active:focus,
+.show>.btn-outline-default.dropdown-toggle {
+  background-color: #66615B !important;
+  color: rgba(255, 255, 255, 0.8);
+  border-color: #66615B !important;
+}
+
+.btn-outline-default:hover .caret,
+.btn-outline-default:focus .caret,
+.btn-outline-default:active .caret,
+.btn-outline-default.active .caret,
+.btn-outline-default:active:focus .caret,
+.btn-outline-default:active:hover .caret,
+.btn-outline-default.active:focus .caret,
+.show>.btn-outline-default.dropdown-toggle .caret {
+  border-top-color: rgba(255, 255, 255, 0.8);
+}
+
+.btn-outline-default .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-outline-default.disabled,
+.btn-outline-default.disabled:hover,
+.btn-outline-default.disabled:focus,
+.btn-outline-default.disabled.focus,
+.btn-outline-default.disabled:active,
+.btn-outline-default.disabled.active,
+.btn-outline-default:disabled,
+.btn-outline-default:disabled:hover,
+.btn-outline-default:disabled:focus,
+.btn-outline-default:disabled.focus,
+.btn-outline-default:disabled:active,
+.btn-outline-default:disabled.active,
+.btn-outline-default[disabled],
+.btn-outline-default[disabled]:hover,
+.btn-outline-default[disabled]:focus,
+.btn-outline-default[disabled].focus,
+.btn-outline-default[disabled]:active,
+.btn-outline-default[disabled].active,
+fieldset[disabled] .btn-outline-default,
+fieldset[disabled] .btn-outline-default:hover,
+fieldset[disabled] .btn-outline-default:focus,
+fieldset[disabled] .btn-outline-default.focus,
+fieldset[disabled] .btn-outline-default:active,
+fieldset[disabled] .btn-outline-default.active {
+  background-color: transparent;
+  border-color: #66615B;
+}
+
+.btn-outline-primary {
+  border-color: #51cbce;
+  color: #51cbce;
+  opacity: 1;
+  filter: alpha(opacity=100);
+}
+
+.btn-outline-primary:hover,
+.btn-outline-primary:focus,
+.btn-outline-primary:active,
+.btn-outline-primary.active,
+.btn-outline-primary:active:focus,
+.btn-outline-primary:active:hover,
+.btn-outline-primary.active:focus,
+.show>.btn-outline-primary.dropdown-toggle {
+  background-color: #51cbce !important;
+  color: rgba(255, 255, 255, 0.8);
+  border-color: #51cbce !important;
+}
+
+.btn-outline-primary:hover .caret,
+.btn-outline-primary:focus .caret,
+.btn-outline-primary:active .caret,
+.btn-outline-primary.active .caret,
+.btn-outline-primary:active:focus .caret,
+.btn-outline-primary:active:hover .caret,
+.btn-outline-primary.active:focus .caret,
+.show>.btn-outline-primary.dropdown-toggle .caret {
+  border-top-color: rgba(255, 255, 255, 0.8);
+}
+
+.btn-outline-primary .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-outline-primary.disabled,
+.btn-outline-primary.disabled:hover,
+.btn-outline-primary.disabled:focus,
+.btn-outline-primary.disabled.focus,
+.btn-outline-primary.disabled:active,
+.btn-outline-primary.disabled.active,
+.btn-outline-primary:disabled,
+.btn-outline-primary:disabled:hover,
+.btn-outline-primary:disabled:focus,
+.btn-outline-primary:disabled.focus,
+.btn-outline-primary:disabled:active,
+.btn-outline-primary:disabled.active,
+.btn-outline-primary[disabled],
+.btn-outline-primary[disabled]:hover,
+.btn-outline-primary[disabled]:focus,
+.btn-outline-primary[disabled].focus,
+.btn-outline-primary[disabled]:active,
+.btn-outline-primary[disabled].active,
+fieldset[disabled] .btn-outline-primary,
+fieldset[disabled] .btn-outline-primary:hover,
+fieldset[disabled] .btn-outline-primary:focus,
+fieldset[disabled] .btn-outline-primary.focus,
+fieldset[disabled] .btn-outline-primary:active,
+fieldset[disabled] .btn-outline-primary.active {
+  background-color: transparent;
+  border-color: #51cbce;
+}
+
+.btn-outline-success {
+  border-color: #6bd098;
+  color: #6bd098;
+  opacity: 1;
+  filter: alpha(opacity=100);
+}
+
+.btn-outline-success:hover,
+.btn-outline-success:focus,
+.btn-outline-success:active,
+.btn-outline-success.active,
+.btn-outline-success:active:focus,
+.btn-outline-success:active:hover,
+.btn-outline-success.active:focus,
+.show>.btn-outline-success.dropdown-toggle {
+  background-color: #6bd098 !important;
+  color: rgba(255, 255, 255, 0.8);
+  border-color: #6bd098 !important;
+}
+
+.btn-outline-success:hover .caret,
+.btn-outline-success:focus .caret,
+.btn-outline-success:active .caret,
+.btn-outline-success.active .caret,
+.btn-outline-success:active:focus .caret,
+.btn-outline-success:active:hover .caret,
+.btn-outline-success.active:focus .caret,
+.show>.btn-outline-success.dropdown-toggle .caret {
+  border-top-color: rgba(255, 255, 255, 0.8);
+}
+
+.btn-outline-success .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-outline-success.disabled,
+.btn-outline-success.disabled:hover,
+.btn-outline-success.disabled:focus,
+.btn-outline-success.disabled.focus,
+.btn-outline-success.disabled:active,
+.btn-outline-success.disabled.active,
+.btn-outline-success:disabled,
+.btn-outline-success:disabled:hover,
+.btn-outline-success:disabled:focus,
+.btn-outline-success:disabled.focus,
+.btn-outline-success:disabled:active,
+.btn-outline-success:disabled.active,
+.btn-outline-success[disabled],
+.btn-outline-success[disabled]:hover,
+.btn-outline-success[disabled]:focus,
+.btn-outline-success[disabled].focus,
+.btn-outline-success[disabled]:active,
+.btn-outline-success[disabled].active,
+fieldset[disabled] .btn-outline-success,
+fieldset[disabled] .btn-outline-success:hover,
+fieldset[disabled] .btn-outline-success:focus,
+fieldset[disabled] .btn-outline-success.focus,
+fieldset[disabled] .btn-outline-success:active,
+fieldset[disabled] .btn-outline-success.active {
+  background-color: transparent;
+  border-color: #6bd098;
+}
+
+.btn-outline-info {
+  border-color: #51bcda;
+  color: #51bcda;
+  opacity: 1;
+  filter: alpha(opacity=100);
+}
+
+.btn-outline-info:hover,
+.btn-outline-info:focus,
+.btn-outline-info:active,
+.btn-outline-info.active,
+.btn-outline-info:active:focus,
+.btn-outline-info:active:hover,
+.btn-outline-info.active:focus,
+.show>.btn-outline-info.dropdown-toggle {
+  background-color: #51bcda !important;
+  color: rgba(255, 255, 255, 0.8);
+  border-color: #51bcda !important;
+}
+
+.btn-outline-info:hover .caret,
+.btn-outline-info:focus .caret,
+.btn-outline-info:active .caret,
+.btn-outline-info.active .caret,
+.btn-outline-info:active:focus .caret,
+.btn-outline-info:active:hover .caret,
+.btn-outline-info.active:focus .caret,
+.show>.btn-outline-info.dropdown-toggle .caret {
+  border-top-color: rgba(255, 255, 255, 0.8);
+}
+
+.btn-outline-info .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-outline-info.disabled,
+.btn-outline-info.disabled:hover,
+.btn-outline-info.disabled:focus,
+.btn-outline-info.disabled.focus,
+.btn-outline-info.disabled:active,
+.btn-outline-info.disabled.active,
+.btn-outline-info:disabled,
+.btn-outline-info:disabled:hover,
+.btn-outline-info:disabled:focus,
+.btn-outline-info:disabled.focus,
+.btn-outline-info:disabled:active,
+.btn-outline-info:disabled.active,
+.btn-outline-info[disabled],
+.btn-outline-info[disabled]:hover,
+.btn-outline-info[disabled]:focus,
+.btn-outline-info[disabled].focus,
+.btn-outline-info[disabled]:active,
+.btn-outline-info[disabled].active,
+fieldset[disabled] .btn-outline-info,
+fieldset[disabled] .btn-outline-info:hover,
+fieldset[disabled] .btn-outline-info:focus,
+fieldset[disabled] .btn-outline-info.focus,
+fieldset[disabled] .btn-outline-info:active,
+fieldset[disabled] .btn-outline-info.active {
+  background-color: transparent;
+  border-color: #51bcda;
+}
+
+.btn-outline-warning {
+  border-color: #fbc658;
+  color: #fbc658;
+  opacity: 1;
+  filter: alpha(opacity=100);
+}
+
+.btn-outline-warning:hover,
+.btn-outline-warning:focus,
+.btn-outline-warning:active,
+.btn-outline-warning.active,
+.btn-outline-warning:active:focus,
+.btn-outline-warning:active:hover,
+.btn-outline-warning.active:focus,
+.show>.btn-outline-warning.dropdown-toggle {
+  background-color: #fbc658 !important;
+  color: rgba(255, 255, 255, 0.8);
+  border-color: #fbc658 !important;
+}
+
+.btn-outline-warning:hover .caret,
+.btn-outline-warning:focus .caret,
+.btn-outline-warning:active .caret,
+.btn-outline-warning.active .caret,
+.btn-outline-warning:active:focus .caret,
+.btn-outline-warning:active:hover .caret,
+.btn-outline-warning.active:focus .caret,
+.show>.btn-outline-warning.dropdown-toggle .caret {
+  border-top-color: rgba(255, 255, 255, 0.8);
+}
+
+.btn-outline-warning .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-outline-warning.disabled,
+.btn-outline-warning.disabled:hover,
+.btn-outline-warning.disabled:focus,
+.btn-outline-warning.disabled.focus,
+.btn-outline-warning.disabled:active,
+.btn-outline-warning.disabled.active,
+.btn-outline-warning:disabled,
+.btn-outline-warning:disabled:hover,
+.btn-outline-warning:disabled:focus,
+.btn-outline-warning:disabled.focus,
+.btn-outline-warning:disabled:active,
+.btn-outline-warning:disabled.active,
+.btn-outline-warning[disabled],
+.btn-outline-warning[disabled]:hover,
+.btn-outline-warning[disabled]:focus,
+.btn-outline-warning[disabled].focus,
+.btn-outline-warning[disabled]:active,
+.btn-outline-warning[disabled].active,
+fieldset[disabled] .btn-outline-warning,
+fieldset[disabled] .btn-outline-warning:hover,
+fieldset[disabled] .btn-outline-warning:focus,
+fieldset[disabled] .btn-outline-warning.focus,
+fieldset[disabled] .btn-outline-warning:active,
+fieldset[disabled] .btn-outline-warning.active {
+  background-color: transparent;
+  border-color: #fbc658;
+}
+
+.btn-outline-danger {
+  border-color: #f5593d;
+  color: #f5593d;
+  opacity: 1;
+  filter: alpha(opacity=100);
+}
+
+.btn-outline-danger:hover,
+.btn-outline-danger:focus,
+.btn-outline-danger:active,
+.btn-outline-danger.active,
+.btn-outline-danger:active:focus,
+.btn-outline-danger:active:hover,
+.btn-outline-danger.active:focus,
+.show>.btn-outline-danger.dropdown-toggle {
+  background-color: #f5593d !important;
+  color: rgba(255, 255, 255, 0.8);
+  border-color: #f5593d !important;
+}
+
+.btn-outline-danger:hover .caret,
+.btn-outline-danger:focus .caret,
+.btn-outline-danger:active .caret,
+.btn-outline-danger.active .caret,
+.btn-outline-danger:active:focus .caret,
+.btn-outline-danger:active:hover .caret,
+.btn-outline-danger.active:focus .caret,
+.show>.btn-outline-danger.dropdown-toggle .caret {
+  border-top-color: rgba(255, 255, 255, 0.8);
+}
+
+.btn-outline-danger .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-outline-danger.disabled,
+.btn-outline-danger.disabled:hover,
+.btn-outline-danger.disabled:focus,
+.btn-outline-danger.disabled.focus,
+.btn-outline-danger.disabled:active,
+.btn-outline-danger.disabled.active,
+.btn-outline-danger:disabled,
+.btn-outline-danger:disabled:hover,
+.btn-outline-danger:disabled:focus,
+.btn-outline-danger:disabled.focus,
+.btn-outline-danger:disabled:active,
+.btn-outline-danger:disabled.active,
+.btn-outline-danger[disabled],
+.btn-outline-danger[disabled]:hover,
+.btn-outline-danger[disabled]:focus,
+.btn-outline-danger[disabled].focus,
+.btn-outline-danger[disabled]:active,
+.btn-outline-danger[disabled].active,
+fieldset[disabled] .btn-outline-danger,
+fieldset[disabled] .btn-outline-danger:hover,
+fieldset[disabled] .btn-outline-danger:focus,
+fieldset[disabled] .btn-outline-danger.focus,
+fieldset[disabled] .btn-outline-danger:active,
+fieldset[disabled] .btn-outline-danger.active {
+  background-color: transparent;
+  border-color: #f5593d;
+}
+
+.btn-outline-neutral {
+  border-color: #FFFFFF;
+  color: #FFFFFF;
+  opacity: 1;
+  filter: alpha(opacity=100);
+}
+
+.btn-outline-neutral:hover,
+.btn-outline-neutral:focus,
+.btn-outline-neutral:active,
+.btn-outline-neutral.active,
+.btn-outline-neutral:active:focus,
+.btn-outline-neutral:active:hover,
+.btn-outline-neutral.active:focus,
+.show>.btn-outline-neutral.dropdown-toggle {
+  background-color: #FFFFFF !important;
+  color: rgba(255, 255, 255, 0.8);
+  border-color: #FFFFFF !important;
+}
+
+.btn-outline-neutral:hover .caret,
+.btn-outline-neutral:focus .caret,
+.btn-outline-neutral:active .caret,
+.btn-outline-neutral.active .caret,
+.btn-outline-neutral:active:focus .caret,
+.btn-outline-neutral:active:hover .caret,
+.btn-outline-neutral.active:focus .caret,
+.show>.btn-outline-neutral.dropdown-toggle .caret {
+  border-top-color: rgba(255, 255, 255, 0.8);
+}
+
+.btn-outline-neutral .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-outline-neutral.disabled,
+.btn-outline-neutral.disabled:hover,
+.btn-outline-neutral.disabled:focus,
+.btn-outline-neutral.disabled.focus,
+.btn-outline-neutral.disabled:active,
+.btn-outline-neutral.disabled.active,
+.btn-outline-neutral:disabled,
+.btn-outline-neutral:disabled:hover,
+.btn-outline-neutral:disabled:focus,
+.btn-outline-neutral:disabled.focus,
+.btn-outline-neutral:disabled:active,
+.btn-outline-neutral:disabled.active,
+.btn-outline-neutral[disabled],
+.btn-outline-neutral[disabled]:hover,
+.btn-outline-neutral[disabled]:focus,
+.btn-outline-neutral[disabled].focus,
+.btn-outline-neutral[disabled]:active,
+.btn-outline-neutral[disabled].active,
+fieldset[disabled] .btn-outline-neutral,
+fieldset[disabled] .btn-outline-neutral:hover,
+fieldset[disabled] .btn-outline-neutral:focus,
+fieldset[disabled] .btn-outline-neutral.focus,
+fieldset[disabled] .btn-outline-neutral:active,
+fieldset[disabled] .btn-outline-neutral.active {
+  background-color: transparent;
+  border-color: #FFFFFF;
+}
+
+.btn-outline-neutral:hover,
+.btn-outline-neutral:focus,
+.btn-outline-neutral:active {
+  color: #403D39 !important;
+  background-color: #FFFFFF;
+}
+
+.btn-neutral {
+  background-color: #FFFFFF;
+  border-color: #FFFFFF;
+  color: #FFFFFF;
+  opacity: 1;
+  filter: alpha(opacity=100);
+  color: #66615B;
+}
+
+.btn-neutral:hover,
+.btn-neutral:focus,
+.btn-neutral:active,
+.btn-neutral.active,
+.btn-neutral:active:focus,
+.btn-neutral:active:hover,
+.btn-neutral.active:focus,
+.btn-neutral:not(:disabled):not(.disabled):active:focus,
+.btn-neutral:not(:disabled):not(.disabled):active,
+.btn-neutral:not(:disabled):not(.disabled).active,
+.btn-neutral:not(:disabled):not(.disabled).active:focus,
+.show>.btn-neutral.dropdown-toggle {
+  background-color: #FFFFFF;
+  color: #FFFFFF;
+  border-color: #FFFFFF;
+  box-shadow: none;
+}
+
+.btn-neutral .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-neutral.disabled,
+.btn-neutral.disabled:hover,
+.btn-neutral.disabled:focus,
+.btn-neutral.disabled.focus,
+.btn-neutral.disabled:active,
+.btn-neutral.disabled.active,
+.btn-neutral:disabled,
+.btn-neutral:disabled:hover,
+.btn-neutral:disabled:focus,
+.btn-neutral:disabled.focus,
+.btn-neutral:disabled:active,
+.btn-neutral:disabled.active,
+.btn-neutral[disabled],
+.btn-neutral[disabled]:hover,
+.btn-neutral[disabled]:focus,
+.btn-neutral[disabled].focus,
+.btn-neutral[disabled]:active,
+.btn-neutral[disabled].active,
+fieldset[disabled] .btn-neutral,
+fieldset[disabled] .btn-neutral:hover,
+fieldset[disabled] .btn-neutral:focus,
+fieldset[disabled] .btn-neutral.focus,
+fieldset[disabled] .btn-neutral:active,
+fieldset[disabled] .btn-neutral.active {
+  background-color: #FFFFFF;
+  border-color: #FFFFFF;
+}
+
+.btn-neutral.btn-link {
+  color: #FFFFFF;
+}
+
+.btn-neutral.btn-link:hover,
+.btn-neutral.btn-link:focus,
+.btn-neutral.btn-link:active,
+.btn-neutral.btn-link.active,
+.btn-neutral.btn-link:focus:active,
+.open>.btn-neutral.btn-link.dropdown-toggle {
+  background-color: transparent !important;
+  color: #FFFFFF !important;
+}
+
+.btn-neutral.btn-link .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-neutral .caret {
+  border-top-color: #FFFFFF;
+}
+
+.btn-neutral:hover,
+.btn-neutral:focus,
+.btn-neutral:active {
+  color: #403D39 !important;
+}
+
+.btn-neutral.btn-border:hover,
+.btn-neutral.btn-border:focus {
+  color: #66615B;
+}
+
+.btn-neutral.btn-border:active,
+.btn-neutral.btn-border.active,
+.open>.btn-neutral.btn-border.dropdown-toggle {
+  background-color: #FFFFFF;
+  color: #66615B;
+}
+
+.btn-neutral.btn-link:hover,
+.btn-neutral.btn-link:focus,
+.btn-neutral.btn-link:active {
+  color: #FFFFFF !important;
+}
+
+.btn-neutral.btn-link:focus:active {
+  color: #403D39 !important;
+}
+
+.btn-neutral.btn-link:active,
+.btn-neutral.btn-link.active {
+  background-color: transparent;
+}
+
+.btn:disabled,
+.btn[disabled],
+.btn.disabled {
+  opacity: 0.5;
+  filter: alpha(opacity=50);
+}
+
+.btn-link {
+  border-color: transparent !important;
+  padding: 7px 18px;
+}
+
+.btn-link:hover,
+.btn-link:focus,
+.btn-link:active {
+  text-decoration: none;
+  border-color: transparent;
+}
+
+.btn-link.btn-icon {
+  padding: 7px;
+}
+
+.btn-lg {
+  font-size: 14px;
+  padding: 11px 30px;
+}
+
+.btn-lg.btn-simple {
+  padding: 13px 30px;
+}
+
+.btn-sm {
+  font-size: 12px;
+  padding: 4px 10px;
+}
+
+.btn-sm.btn-simple {
+  padding: 6px 10px;
+}
+
+.btn-wd {
+  min-width: 140px;
+}
+
+.btn-group.select {
+  width: 100%;
+}
+
+.btn-group.select .btn {
+  text-align: left;
+}
+
+.btn-group.select .caret {
+  position: absolute;
+  top: 50%;
+  margin-top: -1px;
+  right: 8px;
+}
+
+.btn-just-icon.btn-sm {
+  height: 30px;
+  width: 30px;
+  min-width: 30px;
+  padding: 0;
+}
+
+.btn-just-icon.btn-sm i {
+  font-size: 12px;
+  top: 1px !important;
+}
+
+.btn-just-icon.btn-lg {
+  height: 50px;
+  width: 50px;
+  min-width: 50px;
+  padding: 13px;
+}
+
+.btn-just-icon.btn-lg i {
+  font-size: 18px;
+  padding: 0;
+}
+
+.btn-just-icon.btn-link {
+  padding: 8px !important;
+}
+
+.btn-round {
+  border-radius: 30px;
+}
+
+.btn.btn-link:focus {
+  box-shadow: none !important;
+  text-decoration: none;
+}
+
+.column .btn-link {
+  padding: 7px 0;
+}
+
+.share-buttons .btn-outline-default {
+  margin-top: 24px;
+}
+
+.btn-group.select {
+  overflow: visible !important;
+}
+
+.media .media-body .media-footer .btn-neutral {
+  margin: 15px 3px;
+  font-size: 14px;
+}
+
+.media .media-body .media-footer .btn-neutral i {
+  margin-right: 0 !important;
+}
+
+::-moz-placeholder {
+  color: #9A9A9A;
+}
+
+:-ms-input-placeholder {
+  color: #9A9A9A;
+}
+
+::-webkit-input-placeholder {
+  color: #9A9A9A;
+}
+
+.form-control:focus+.input-group-text {
+  border: 1px solid black;
+}
+
+.form-control {
+  background-color: #FFFFFF;
+  border: 1px solid #DDDDDD;
+  border-radius: 4px;
+  color: #66615b;
+  font-size: 14px;
+  transition: background-color 0.3s ease 0s;
+  padding-right: 0 !important;
+  padding: 7px 12px;
+  height: 40px;
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
+
+.form-control:focus {
+  background-color: #FFFFFF;
+  border: 1px solid #ccc;
+  -webkit-box-shadow: none;
+  box-shadow: none;
+  outline: 0 !important;
+}
+
+.form-control:focus+.input-group-prepend .input-group-text,
+.form-control:focus+.input-group-append .input-group-text {
+  border: 1px solid #ccc;
+  border-left: none;
+}
+
+.form-control.no-border {
+  border: medium none !important;
+}
+
+.form-control.no-border:focus+.input-group-prepend .input-group-text,
+.form-control.no-border:focus+.input-group-append .input-group-text {
+  border: none;
+}
+
+.has-success .form-control,
+.has-error .form-control,
+.has-success .form-control:focus,
+.has-error .form-control:focus {
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
+
+.has-success .form-control {
+  border: 1px solid #ccc;
+  color: #66615b;
+}
+
+.has-success .form-control.form-control-success {
+  padding-right: 2.5em !important;
+}
+
+.has-success .form-control:focus {
+  border: 1px solid #6bd098;
+  color: #6bd098;
+}
+
+.has-danger .form-control {
+  background-color: #FFC0A4;
+  border: 1px solid #f5593d;
+  color: #f5593d;
+}
+
+.has-danger .form-control.form-control-danger {
+  padding-right: 2.5em !important;
+}
+
+.has-danger .form-control:focus {
+  background-color: #FFFFFF;
+  border: 1px solid #f5593d;
+}
+
+.form-control+.form-control-feedback {
+  border-radius: 6px;
+  font-size: 14px;
+  color: #f5593d;
+  font-size: .8rem;
+  position: absolute;
+  top: 100%;
+  padding-left: 12px;
+  vertical-align: middle;
+}
+
+.open .form-control {
+  border-radius: 4px 4px 0 0;
+  border-bottom-color: transparent;
+}
+
+.form-control.form-control-lg {
+  height: 55px;
+  padding: 11px 13px;
+  font-size: 1.25rem;
+  line-height: 1.5;
+}
+
+.form-control.form-control-sm {
+  padding: .25rem .5rem;
+  font-size: .875rem;
+  line-height: 1.5;
+  height: 31px;
+}
+
+.has-error .form-control-feedback,
+.has-error .control-label {
+  color: #f5593d;
+}
+
+.has-success .form-control-feedback,
+.has-success .control-label {
+  color: #6bd098;
+}
+
+.input-group-prepend+.form-control {
+  margin-left: -1px;
+  border-left: none;
+}
+
+.form-control+.input-group-append .input-group-text {
+  border-right: 1px solid #ddd;
+}
+
+.input-group>.custom-select:not(:last-child),
+.input-group>.form-control:not(:last-child) {
+  border-right: none;
+}
+
+.input-group-text {
+  background-color: #FFFFFF;
+  border-radius: 4px;
+  border: 1px solid #ddd;
+  border-right: none;
+}
+
+.has-success .input-group-text,
+.has-error .input-group-text {
+  background-color: #FFFFFF;
+}
+
+.has-error .form-control:focus+.input-group-text {
+  color: #f5593d;
+}
+
+.has-success .form-control:focus+.input-group-text {
+  color: #6bd098;
+}
+
+.form-control:focus+.input-group-text,
+.form-control:focus~.input-group-text {
+  background-color: #FFFFFF;
+}
+
+.input-group.no-border .input-group-text {
+  border: 0;
+}
+
+textarea.form-control {
+  padding: 10px 18px;
+  height: auto;
+}
+
+.form-group {
+  position: relative;
+}
+
+.register-form .form-control {
+  border: 1px solid transparent !important;
+}
+
+.register-form .input-group .form-control {
+  margin-left: -1px;
+}
+
+.register-form .input-group-prepend,
+.register-form .input-group-append {
+  border: 1px solid transparent !important;
+}
+
+#inputs .input-group {
+  margin-bottom: 1rem;
+}
+
+.card-form-horizontal .card-body .form-group {
+  margin-bottom: 0;
+}
+
+.from-check,
+.form-check-radio {
+  margin-bottom: 12px;
+  position: relative;
+}
+
+.form-check {
+  padding-left: 0;
+  margin-bottom: .5rem;
+}
+
+.form-check .form-check-label {
+  display: inline-block;
+  position: relative;
+  cursor: pointer;
+  padding-left: 35px;
+  line-height: 26px;
+  margin-bottom: 0;
+}
+
+.form-check .form-check-sign::before,
+.form-check .form-check-sign::after {
+  content: " ";
+  display: inline-block;
+  position: absolute;
+  width: 24px;
+  height: 24px;
+  left: 0;
+  cursor: pointer;
+  border-radius: 6px;
+  top: 0;
+  background-color: #AAA7A4;
+  -webkit-transition: opacity 0.3s linear;
+  -moz-transition: opacity 0.3s linear;
+  -o-transition: opacity 0.3s linear;
+  -ms-transition: opacity 0.3s linear;
+  transition: opacity 0.3s linear;
+}
+
+.form-check .form-check-sign::after {
+  font-family: 'FontAwesome';
+  content: "\f00c";
+  top: -1px;
+  text-align: center;
+  font-size: 15px;
+  opacity: 0;
+  color: #FFF;
+  border: 0;
+  background-color: inherit;
+}
+
+.form-check.disabled .form-check-label {
+  color: #9A9A9A;
+  opacity: .5;
+  cursor: not-allowed;
+}
+
+.form-check input[type="checkbox"],
+.form-check-radio input[type="radio"] {
+  opacity: 0;
+  position: absolute;
+  visibility: hidden;
+}
+
+.form-check input[type="checkbox"]:checked+.form-check-sign::after {
+  opacity: 1;
+}
+
+.form-control input[type="checkbox"]:disabled+.form-check-sign::before,
+.checkbox input[type="checkbox"]:disabled+.form-check-sign::after {
+  cursor: not-allowed;
+}
+
+.form-check .form-check-label input[type="checkbox"]:disabled+.form-check-sign,
+.form-check-radio input[type="radio"]:disabled+.form-check-sign {
+  pointer-events: none !important;
+}
+
+.form-check-radio {
+  margin-left: -3px;
+}
+
+.form-check-radio .form-check-label {
+  padding-left: 2rem;
+}
+
+.form-check-radio.disabled .form-check-label {
+  color: #9A9A9A;
+  opacity: .5;
+  cursor: not-allowed;
+}
+
+.form-check-radio .form-check-sign::before {
+  font-family: 'FontAwesome';
+  content: "\f10c";
+  font-size: 22px;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  display: inline-block;
+  position: absolute;
+  opacity: .50;
+  left: 5px;
+  top: -5px;
+}
+
+.form-check-label input[type="checkbox"]:checked+.form-check-sign:before {
+  background-color: #66615B;
+}
+
+.form-check-radio input[type="radio"]+.form-check-sign:after,
+.form-check-radio input[type="radio"] {
+  opacity: 0;
+  -webkit-transition: opacity 0.3s linear;
+  -moz-transition: opacity 0.3s linear;
+  -o-transition: opacity 0.3s linear;
+  -ms-transition: opacity 0.3s linear;
+  transition: opacity 0.3s linear;
+  content: " ";
+  display: block;
+}
+
+.form-check-radio input[type="radio"]:checked+.form-check-sign::after {
+  font-family: 'FontAwesome';
+  content: "\f192";
+  top: -5px;
+  position: absolute;
+  left: 5px;
+  opacity: 1;
+  font-size: 22px;
+}
+
+.form-check-radio input[type="radio"]:checked+.form-check-sign::after {
+  opacity: 1;
+}
+
+.form-check-radio input[type="radio"]:disabled+.form-check-sign::before,
+.form-check-radio input[type="radio"]:disabled+.form-check-sign::after {
+  color: #9A9A9A;
+}
+
+.progress {
+  background-color: #DDDDDD;
+  border-radius: 3px;
+  box-shadow: none;
+  height: 8px;
+}
+
+.progress-thin {
+  height: 4px;
+}
+
+.progress-bar {
+  background-color: #51cbce;
+}
+
+.progress-bar-primary {
+  background-color: #51cbce;
+}
+
+.progress-bar-info {
+  background-color: #51bcda;
+}
+
+.progress-bar-success {
+  background-color: #6bd098;
+}
+
+.progress-bar-warning {
+  background-color: #fbc658;
+}
+
+.progress-bar-danger {
+  background-color: #f5593d;
+}
+
+/*           badges & Progress-bar              */
+
+.badge {
+  padding: 0.4em 0.9em;
+  color: #FFFFFF;
+  font-weight: 500;
+  font-size: 0.75em;
+  text-transform: uppercase;
+  display: inline-block;
+  margin-bottom: 3px;
+  padding-top: 5px;
+}
+
+.badge:focus {
+  outline: none;
+}
+
+.badge span[data-role="remove"]:focus {
+  outline: none;
+}
+
+.badge-primary {
+  background-color: #51cbce;
+}
+
+.badge-info {
+  background-color: #51bcda;
+}
+
+.badge-success {
+  background-color: #6bd098;
+}
+
+.badge-warning {
+  background-color: #fbc658;
+}
+
+.badge-danger {
+  background-color: #f5593d;
+}
+
+.badge-default {
+  background-color: #66615B;
+}
+
+.pagination>li>a,
+.pagination>li>span,
+.pagination>li:first-child>a,
+.pagination>li:first-child>span,
+.pagination>li:last-child>a,
+.pagination>li:last-child>span {
+  background-color: transparent;
+  border: 2px solid #f5593d;
+  border-radius: 20px;
+  color: #f5593d;
+  height: 36px;
+  margin: 0 2px;
+  min-width: 36px;
+  padding: 8px 12px;
+  font-weight: 600;
+}
+
+.nav-pills-default>li>a,
+.pagination>li>a:hover,
+.pagination>li>a:focus,
+.pagination>li>a:active,
+.pagination>li.active>a,
+.pagination>li.active>span,
+.pagination>li.active>a:hover,
+.pagination>li.active>span:hover,
+.pagination>li.active>a:focus,
+.pagination>li.active>span:focus {
+  background-color: #66615B;
+  border-color: #66615B;
+  color: #FFFFFF;
+}
+
+.nav-pills-primary>li>a,
+.pagination-primary>li>a,
+.pagination-primary>li>span,
+.pagination-primary>li:first-child>a,
+.pagination-primary>li:first-child>span,
+.pagination-primary>li:last-child>a,
+.pagination-primary>li:last-child>span {
+  border: 2px solid #51cbce;
+  color: #51cbce;
+}
+
+.nav-pills-primary>li.active>a,
+.nav-pills-primary>li.active>a:hover,
+.nav-pills-primary>li.active>a:focus,
+.pagination-primary>li>a:hover,
+.pagination-primary>li>a:focus,
+.pagination-primary>li>a:active,
+.pagination-primary>li.active>a,
+.pagination-primary>li.active>span,
+.pagination-primary>li.active>a:hover,
+.pagination-primary>li.active>span:hover,
+.pagination-primary>li.active>a:focus,
+.pagination-primary>li.active>span:focus {
+  background-color: #51cbce !important;
+  border-color: #51cbce !important;
+  color: #FFFFFF;
+}
+
+.nav-pills-info>li>a,
+.pagination-info>li>a,
+.pagination-info>li>span,
+.pagination-info>li:first-child>a,
+.pagination-info>li:first-child>span,
+.pagination-info>li:last-child>a,
+.pagination-info>li:last-child>span {
+  border: 2px solid #51bcda;
+  color: #51bcda;
+}
+
+.nav-pills-info>li.active>a,
+.nav-pills-info>li.active>a:hover,
+.nav-pills-info>li.active>a:focus,
+.pagination-info>li>a:hover,
+.pagination-info>li>a:focus,
+.pagination-info>li>a:active,
+.pagination-info>li.active>a,
+.pagination-info>li.active>span,
+.pagination-info>li.active>a:hover,
+.pagination-info>li.active>span:hover,
+.pagination-info>li.active>a:focus,
+.pagination-info>li.active>span:focus {
+  background-color: #51bcda !important;
+  border-color: #51bcda !important;
+  color: #FFFFFF;
+}
+
+.nav-pills-success>li>a,
+.pagination-success>li>a,
+.pagination-success>li>span,
+.pagination-success>li:first-child>a,
+.pagination-success>li:first-child>span,
+.pagination-success>li:last-child>a,
+.pagination-success>li:last-child>span {
+  border: 2px solid #6bd098;
+  color: #6bd098;
+}
+
+.nav-pills-success>li.active>a,
+.nav-pills-success>li.active>a:hover,
+.nav-pills-success>li.active>a:focus,
+.pagination-success>li>a:hover,
+.pagination-success>li>a:focus,
+.pagination-success>li>a:active,
+.pagination-success>li.active>a,
+.pagination-success>li.active>span,
+.pagination-success>li.active>a:hover,
+.pagination-success>li.active>span:hover,
+.pagination-success>li.active>a:focus,
+.pagination-success>li.active>span:focus {
+  background-color: #6bd098 !important;
+  border-color: #6bd098 !important;
+  color: #FFFFFF;
+}
+
+.nav-pills-warning>li>a,
+.pagination-warning>li>a,
+.pagination-warning>li>span,
+.pagination-warning>li:first-child>a,
+.pagination-warning>li:first-child>span,
+.pagination-warning>li:last-child>a,
+.pagination-warning>li:last-child>span {
+  border: 2px solid #fbc658;
+  color: #fbc658;
+}
+
+.nav-pills-warning>li.active>a,
+.nav-pills-warning>li.active>a:hover,
+.nav-pills-warning>li.active>a:focus,
+.pagination-warning>li>a:hover,
+.pagination-warning>li>a:focus,
+.pagination-warning>li>a:active,
+.pagination-warning>li.active>a,
+.pagination-warning>li.active>span,
+.pagination-warning>li.active>a:hover,
+.pagination-warning>li.active>span:hover,
+.pagination-warning>li.active>a:focus,
+.pagination-warning>li.active>span:focus {
+  background-color: #fbc658 !important;
+  border-color: #fbc658 !important;
+  color: #FFFFFF;
+}
+
+.nav-pills-danger>li>a,
+.pagination-danger>li>a,
+.pagination-danger>li>span,
+.pagination-danger>li:first-child>a,
+.pagination-danger>li:first-child>span,
+.pagination-danger>li:last-child>a,
+.pagination-danger>li:last-child>span {
+  border: 2px solid #f5593d;
+  color: #f5593d;
+}
+
+.nav-pills-danger>li.active>a,
+.nav-pills-danger>li.active>a:hover,
+.nav-pills-danger>li.active>a:focus,
+.pagination-danger>li>a:hover,
+.pagination-danger>li>a:focus,
+.pagination-danger>li>a:active,
+.pagination-danger>li.active>a,
+.pagination-danger>li.active>span,
+.pagination-danger>li.active>a:hover,
+.pagination-danger>li.active>span:hover,
+.pagination-danger>li.active>a:focus,
+.pagination-danger>li.active>span:focus {
+  background-color: #f5593d !important;
+  border-color: #f5593d !important;
+  color: #FFFFFF;
+}
+
+.nav-text,
+.nav-icons {
+  margin: 0 0 10px 0;
+}
+
+.nav-text>li>a,
+.nav-icons>li>a {
+  display: block;
+  padding: 0px 18px;
+  color: #9A9A9A;
+  text-align: center;
+  opacity: 0.8;
+  filter: alpha(opacity=80);
+}
+
+.nav-text>li>a:hover,
+.nav-text>li>a:focus,
+.nav-icons>li>a:hover,
+.nav-icons>li>a:focus {
+  background-color: transparent;
+  opacity: 1;
+  filter: alpha(opacity=100);
+}
+
+.nav-text>li:first-child a,
+.nav-icons>li:first-child a {
+  padding-left: 0;
+}
+
+.nav-text>li.active a,
+.nav-icons>li.active a {
+  color: #51bcda;
+}
+
+.nav-icons>li {
+  display: inline-block;
+}
+
+.nav-icons>li>a {
+  padding: 0 10px;
+  margin-bottom: 10px;
+}
+
+.nav-icons>li>a i {
+  font-size: 1.6em;
+  margin-bottom: 10px;
+  width: 1.6em;
+}
+
+.nav-icons.nav-stacked>li {
+  display: block;
+}
+
+.nav-icons.nav-stacked>li>a {
+  margin-bottom: 20px;
+}
+
+.nav-blue>li.active a {
+  color: #51cbce;
+}
+
+.nav-azure>li.active a {
+  color: #51bcda;
+}
+
+.nav-green>li.active a {
+  color: #6bd098;
+}
+
+.nav-orange>li.active a {
+  color: #fbc658;
+}
+
+.nav-red>li.active a {
+  color: #f5593d;
+}
+
+.nav-text {
+  margin: 0 0 10px 0;
+}
+
+.nav-text>li>a {
+  font-size: 0.9em;
+  text-transform: uppercase;
+  padding: 3px 0;
+  text-align: left;
+  font-weight: 500;
+}
+
+.nav-text>li:first-child>a {
+  padding-top: 0;
+}
+
+.nav-text h4 {
+  margin-top: 0;
+}
+
+.nav-text:not(.nav-stacked)>li {
+  display: inline-block;
+}
+
+.nav-text:not(.nav-stacked)>li>a {
+  margin-right: 15px;
+}
+
+.page-item:first-child .page-link,
+.page-item:last-child .page-link {
+  border-bottom-left-radius: 20px;
+  border-top-left-radius: 20px;
+  border-bottom-right-radius: 20px;
+  border-top-right-radius: 20px;
+}
+
+.nav-pills-default .nav-item.show .nav-link,
+.nav-pills-default .nav-link.active {
+  background-color: #66615B !important;
+}
+
+.nav-pills-primary .nav-item.show .nav-link,
+.nav-pills-primary .nav-link.active {
+  background-color: #51cbce !important;
+}
+
+.nav-pills-info .nav-item.show .nav-link,
+.nav-pills-info .nav-link.active {
+  background-color: #51bcda !important;
+}
+
+.nav-pills-warning .nav-item.show .nav-link,
+.nav-pills-warning .nav-link.active {
+  background-color: #fbc658 !important;
+}
+
+.nav-pills-success .nav-item.show .nav-link,
+.nav-pills-success .nav-link.active {
+  background-color: #6bd098 !important;
+}
+
+.nav-pills-danger .nav-item.show .nav-link,
+.nav-pills-danger .nav-link.active {
+  background-color: #f5593d !important;
+}
+
+.pagination>li>a:hover,
+.pagination>li>a:focus,
+.pagination>li>a:active,
+.pagination>li.active>a,
+.pagination>li.active>span,
+.pagination>li.active>a:hover,
+.pagination>li.active>span:hover,
+.pagination>li.active>a:focus,
+.pagination>li.active>span:focus {
+  background-color: #f5593d;
+  border-color: #f5593d;
+  color: #FFFFFF;
+}
+
+.page-item.active .page-link {
+  background-color: #f5593d;
+  color: white;
+  border-color: #f5593d;
+}
+
+.nav-pills .nav-link {
+  border-radius: 0;
+}
+
+.pagination .page-link {
+  box-shadow: none;
+}
+
+/*           Font Smoothing      */
+
+h1,
+.h1,
+h2,
+.h2,
+h3,
+.h3,
+h4,
+.h4,
+h5,
+.h5,
+h6,
+.h6,
+p,
+.navbar,
+.brand,
+a,
+.td-name,
+td,
+button,
+input,
+select,
+textarea {
+  -moz-osx-font-smoothing: grayscale;
+  -webkit-font-smoothing: antialiased;
+  font-family: "Montserrat", "Helvetica", Arial, sans-serif;
+  font-weight: 300;
+}
+
+h1,
+.h1,
+h2,
+.h2,
+h3,
+.h3,
+h4,
+.h4 {
+  margin: 30px 0 0;
+}
+
+h1,
+.h1 {
+  font-size: 3.6em;
+}
+
+h2,
+.h2 {
+  font-size: 2.8em;
+}
+
+h3,
+.h3 {
+  font-size: 1.825em;
+  line-height: 1.4;
+  margin: 20px 0 0px;
+}
+
+h4,
+.h4 {
+  font-size: 1.6em;
+  line-height: 1.2em;
+}
+
+h5,
+.h5 {
+  font-size: 1.35em;
+  line-height: 1.4em;
+}
+
+h6,
+.h6 {
+  font-size: 0.9em;
+  font-weight: 600;
+  text-transform: uppercase;
+  line-height: 1.5em;
+}
+
+p {
+  font-size: 15px;
+  line-height: 1.5em;
+  margin-bottom: 5px;
+}
+
+h1 small,
+h2 small,
+h3 small,
+h4 small,
+h5 small,
+h6 small,
+.h1 small,
+.h2 small,
+.h3 small,
+.h4 small,
+.h5 small,
+.h6 small,
+h1 .small,
+h2 .small,
+h3 .small,
+h4 .small,
+h5 .small,
+h6 .small,
+.h1 .small,
+.h2 .small,
+.h3 .small,
+.h4 .small,
+.h5 .small,
+.h6 .small {
+  color: #9A9A9A;
+  line-height: 1.5em;
+}
+
+h1 small,
+h2 small,
+h3 small,
+h1 .small,
+h2 .small,
+h3 .small {
+  font-size: 60%;
+}
+
+.title,
+.card-title,
+.info-title,
+.footer-brand,
+.footer-big h5,
+.footer-big h4,
+.media .media-heading {
+  font-family: "Montserrat", "Helvetica", Arial, sans-serif;
+}
+
+.title,
+.title a,
+.card-title,
+.card-title a,
+.info-title,
+.info-title a,
+.footer-brand,
+.footer-brand a,
+.footer-big h5,
+.footer-big h5 a,
+.footer-big h4,
+.footer-big h4 a,
+.media .media-heading,
+.media .media-heading a {
+  color: #333333;
+  text-decoration: none;
+}
+
+.title-uppercase {
+  text-transform: uppercase;
+}
+
+.description {
+  color: #9A9A9A;
+}
+
+blockquote small {
+  font-style: normal;
+}
+
+.text-muted {
+  color: #DDDDDD;
+}
+
+.text-primary,
+.text-primary:hover {
+  color: #51cbce !important;
+}
+
+.text-info,
+.text-info:hover {
+  color: #51bcda !important;
+}
+
+.text-success,
+.text-success:hover {
+  color: #6bd098 !important;
+}
+
+.text-warning,
+.text-warning:hover {
+  color: #fbc658 !important;
+}
+
+.text-danger,
+.text-danger:hover {
+  color: #f5593d !important;
+}
+
+.glyphicon {
+  line-height: 1;
+}
+
+.heart {
+  color: #EB5E28;
+  animation: heathing 1s ease infinite;
+}
+
+@keyframes heathing {
+  0% {
+    transform: scale(0.75);
+  }
+  20% {
+    transform: scale(1);
+  }
+  40% {
+    transform: scale(0.75);
+  }
+  60% {
+    transform: scale(1);
+  }
+  80% {
+    transform: scale(0.75);
+  }
+  100% {
+    transform: scale(0.75);
+  }
+}
+
+.footer .credits,
+.footer-nav {
+  line-height: 85px;
+}
+
+.footer .btn {
+  margin-bottom: 0;
+}
+
+.blockquote {
+  border-left: 0 none;
+  border-bottom: 1px solid #CCC5B9;
+  border-top: 1px solid #CCC5B9;
+  font-weight: 300;
+  margin: 15px 0 10px;
+  text-align: center;
+}
+
+.title {
+  margin-top: 30px;
+  margin-bottom: 25px;
+  min-height: 32px;
+}
+
+.title.text-center {
+  margin-bottom: 50px;
+}
+
+/*     General overwrite     */
+
+body {
+  color: #66615b;
+  font-size: 14px;
+  font-weight: 300;
+  font-family: 'Montserrat', "Helvetica", Arial, sans-serif;
+}
+
+a {
+  color: #51bcda;
+}
+
+a:hover,
+a:focus {
+  color: #2ba9cd;
+  text-decoration: none;
+}
+
+hr {
+  border-color: #F1EAE0;
+}
+
+.icon {
+  fill: #66615b;
+}
+
+.fa-base {
+  font-size: 1.25em !important;
+}
+
+a:focus,
+a:active,
+button::-moz-focus-inner,
+input[type="reset"]::-moz-focus-inner,
+input[type="button"]::-moz-focus-inner,
+input[type="submit"]::-moz-focus-inner,
+select::-moz-focus-inner,
+input[type="file"]>input[type="button"]::-moz-focus-inner {
+  outline: 0;
+}
+
+.ui-slider-handle:focus,
+.navbar-toggle {
+  outline: 0 !important;
+}
+
+/*           Animations              */
+
+.form-control,
+.input-group-addon,
+.tagsinput,
+.navbar,
+.navbar .alert,
+.carousel-control.right,
+.carousel-control.left {
+  -webkit-transition: all 300ms linear;
+  -moz-transition: all 300ms linear;
+  -o-transition: all 300ms linear;
+  -ms-transition: all 300ms linear;
+  transition: all 300ms linear;
+}
+
+.tagsinput .tag,
+.tagsinput-remove-link,
+.filter,
+.btn-hover,
+[data-toggle="collapse"] i,
+.animation-transition-fast,
+.dropdown-menu .dropdown-item {
+  -webkit-transition: all 150ms linear;
+  -moz-transition: all 150ms linear;
+  -o-transition: all 150ms linear;
+  -ms-transition: all 150ms linear;
+  transition: all 150ms linear;
+}
+
+.btn-morphing .fa,
+.btn-morphing .circle,
+.gsdk-collapse {
+  -webkit-transition: all 300ms linear;
+  -moz-transition: all 300ms linear;
+  -o-transition: all 300ms linear;
+  -ms-transition: all 300ms linear;
+  transition: all 300ms linear;
+}
+
+.fa {
+  width: 18px;
+  text-align: center;
+}
+
+.margin-top {
+  margin-top: 50px;
+}
+
+.iframe-container iframe {
+  box-shadow: 0 16px 38px -12px rgba(0, 0, 0, 0.56), 0 4px 25px 0 rgba(0, 0, 0, 0.12), 0 8px 10px -5px rgba(0, 0, 0, 0.2);
+}
+
+/*       CT colors          */
+
+.ct-blue {
+  color: #51cbce;
+}
+
+.ct-azure {
+  color: #51bcda;
+}
+
+.ct-green {
+  color: #6bd098;
+}
+
+.ct-orange {
+  color: #fbc658;
+}
+
+.ct-red {
+  color: #f5593d;
+}
+
+.pagination .page-item .page-link .fa {
+  width: auto;
+  font-weight: 600;
+}
+
+.bg-primary {
+  background-color: #6dd3d6 !important;
+}
+
+.bg-info {
+  background-color: #6ec7e0 !important;
+}
+
+.bg-success {
+  background-color: #86d9ab !important;
+}
+
+.bg-warning {
+  background-color: #fcd27b !important;
+}
+
+.bg-danger {
+  background-color: #f7765f !important;
+}
+
+.wrapper {
+  -webkit-transition: all 0.5s cubic-bezier(0.685, 0.0473, 0.346, 1);
+  transition: all 0.5s cubic-bezier(0.685, 0.0473, 0.346, 1);
+  left: 0;
+  background-color: #FFFFFF;
+  position: relative;
+  z-index: 1;
+}
+
+.heart {
+  color: #EB5E28;
+  animation: heathing 1s ease infinite;
+}
+
+@keyframes heathing {
+  0% {
+    transform: scale(0.75);
+  }
+  20% {
+    transform: scale(1);
+  }
+  40% {
+    transform: scale(0.75);
+  }
+  60% {
+    transform: scale(1);
+  }
+  80% {
+    transform: scale(0.75);
+  }
+  100% {
+    transform: scale(0.75);
+  }
+}
+
+.bd-docs .page-header {
+  min-height: 50vh;
+}
+
+.offline-doc .navbar.navbar-transparent {
+  padding-top: 25px;
+  border-bottom: none;
+}
+
+.offline-doc .navbar.navbar-transparent .navbar-minimize {
+  display: none;
+}
+
+.offline-doc .navbar.navbar-transparent .navbar-brand,
+.offline-doc .navbar.navbar-transparent .collapse .navbar-nav .nav-link {
+  color: #FFFFFF !important;
+}
+
+.offline-doc .footer {
+  position: absolute;
+  width: 100%;
+  background: transparent;
+  bottom: 0;
+  z-index: 3;
+}
+
+.offline-doc .footer nav>ul a:not(.btn),
+.offline-doc .footer .copyright {
+  color: #FFFFFF !important;
+}
+
+.offline-doc .page-header .page-header-image {
+  position: absolute;
+  background-size: cover;
+  background-position: center center;
+  width: 100%;
+  height: 100%;
+  z-index: -1;
+}
+
+.offline-doc .page-header .container {
+  z-index: 3;
+}
+
+.offline-doc .page-header:after {
+  background-color: rgba(0, 0, 0, 0.5);
+  content: "";
+  display: block;
+  height: 100%;
+  left: 0;
+  position: absolute;
+  top: 0;
+  width: 100%;
+  z-index: 2;
+}
+
+.main .section:first-of-type {
+  position: relative;
+  z-index: 2;
+}
+
+/*           Labels & Progress-bar              */
+
+.label {
+  padding: 0.2em 0.6em;
+  border-radius: 10px;
+  color: #FFFFFF;
+  font-weight: 500;
+  font-size: 0.75em;
+  text-transform: uppercase;
+  display: inline-block;
+  margin-bottom: 3px;
+  line-height: 17px;
+}
+
+.label-primary {
+  background-color: #51cbce;
+}
+
+.label-info {
+  background-color: #51bcda;
+}
+
+.label-success {
+  background-color: #6bd098;
+}
+
+.label-warning {
+  background-color: #fbc658;
+}
+
+.label-danger {
+  background-color: #f5593d;
+}
+
+.label-default {
+  background-color: #66615B;
+}
+
+/*--------------------------------
+
+nucleo-icons Web Font - built using nucleoapp.com
+License - nucleoapp.com/license/
+
+-------------------------------- */
+
+@font-face {
+  font-family: 'nucleo-icons';
+  src: url("../fonts/nucleo-icons.eot");
+  src: url("../fonts/nucleo-icons.eot") format("embedded-opentype"), url("../fonts/nucleo-icons.woff2") format("woff2"), url("../fonts/nucleo-icons.woff") format("woff"), url("../fonts/nucleo-icons.ttf") format("truetype"), url("../fonts/nucleo-icons.svg") format("svg");
+  font-weight: normal;
+  font-style: normal;
+}
+
+/*------------------------
+	base class definition
+-------------------------*/
+
+.nc-icon {
+  display: inline-block;
+  font: normal normal normal 14px/1 'nucleo-icons';
+  font-size: inherit;
+  speak: none;
+  text-transform: none;
+  /* Better Font Rendering */
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+/*------------------------
+  change icon size
+-------------------------*/
+
+.nc-icon.lg {
+  font-size: 1.33333333em;
+  vertical-align: -16%;
+}
+
+.nc-icon.x2 {
+  font-size: 2em;
+}
+
+.nc-icon.x3 {
+  font-size: 3em;
+}
+
+/*----------------------------------
+  add a square/circle background
+-----------------------------------*/
+
+.nc-icon.square,
+.nc-icon.circle {
+  padding: 0.33333333em;
+  vertical-align: -16%;
+  background-color: #eee;
+}
+
+.nc-icon.circle {
+  border-radius: 50%;
+}
+
+/*------------------------
+  list icons
+-------------------------*/
+
+.nc-icon-ul {
+  padding-left: 0;
+  margin-left: 2.14285714em;
+  list-style-type: none;
+}
+
+.nc-icon-ul>li {
+  position: relative;
+}
+
+.nc-icon-ul>li>.nc-icon {
+  position: absolute;
+  left: -1.57142857em;
+  top: 0.14285714em;
+  text-align: center;
+}
+
+.nc-icon-ul>li>.nc-icon.lg {
+  top: 0;
+  left: -1.35714286em;
+}
+
+.nc-icon-ul>li>.nc-icon.circle,
+.nc-icon-ul>li>.nc-icon.square {
+  top: -0.19047619em;
+  left: -1.9047619em;
+}
+
+/*------------------------
+  spinning icons
+-------------------------*/
+
+.nc-icon.spin {
+  -webkit-animation: nc-icon-spin 2s infinite linear;
+  -moz-animation: nc-icon-spin 2s infinite linear;
+  animation: nc-icon-spin 2s infinite linear;
+}
+
+@-webkit-keyframes nc-icon-spin {
+  0% {
+    -webkit-transform: rotate(0deg);
+  }
+  100% {
+    -webkit-transform: rotate(360deg);
+  }
+}
+
+@-moz-keyframes nc-icon-spin {
+  0% {
+    -moz-transform: rotate(0deg);
+  }
+  100% {
+    -moz-transform: rotate(360deg);
+  }
+}
+
+@keyframes nc-icon-spin {
+  0% {
+    -webkit-transform: rotate(0deg);
+    -moz-transform: rotate(0deg);
+    -ms-transform: rotate(0deg);
+    -o-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  100% {
+    -webkit-transform: rotate(360deg);
+    -moz-transform: rotate(360deg);
+    -ms-transform: rotate(360deg);
+    -o-transform: rotate(360deg);
+    transform: rotate(360deg);
+  }
+}
+
+/*------------------------
+  rotated/flipped icons
+-------------------------*/
+
+.nc-icon.rotate-90 {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
+  -webkit-transform: rotate(90deg);
+  -moz-transform: rotate(90deg);
+  -ms-transform: rotate(90deg);
+  -o-transform: rotate(90deg);
+  transform: rotate(90deg);
+}
+
+.nc-icon.rotate-180 {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
+  -webkit-transform: rotate(180deg);
+  -moz-transform: rotate(180deg);
+  -ms-transform: rotate(180deg);
+  -o-transform: rotate(180deg);
+  transform: rotate(180deg);
+}
+
+.nc-icon.rotate-270 {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
+  -webkit-transform: rotate(270deg);
+  -moz-transform: rotate(270deg);
+  -ms-transform: rotate(270deg);
+  -o-transform: rotate(270deg);
+  transform: rotate(270deg);
+}
+
+.nc-icon.flip-y {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0);
+  -webkit-transform: scale(-1, 1);
+  -moz-transform: scale(-1, 1);
+  -ms-transform: scale(-1, 1);
+  -o-transform: scale(-1, 1);
+  transform: scale(-1, 1);
+}
+
+.nc-icon.flip-x {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
+  -webkit-transform: scale(1, -1);
+  -moz-transform: scale(1, -1);
+  -ms-transform: scale(1, -1);
+  -o-transform: scale(1, -1);
+  transform: scale(1, -1);
+}
+
+/*------------------------
+	font icons
+-------------------------*/
+
+.nc-air-baloon::before {
+  content: "\ea01";
+}
+
+.nc-album-2::before {
+  content: "\ea02";
+}
+
+.nc-alert-circle-i::before {
+  content: "\ea04";
+}
+
+.nc-align-center::before {
+  content: "\ea03";
+}
+
+.nc-align-left-2::before {
+  content: "\ea05";
+}
+
+.nc-ambulance::before {
+  content: "\ea06";
+}
+
+.nc-app::before {
+  content: "\ea07";
+}
+
+.nc-atom::before {
+  content: "\ea08";
+}
+
+.nc-badge::before {
+  content: "\ea09";
+}
+
+.nc-bag-16::before {
+  content: "\ea0a";
+}
+
+.nc-bank::before {
+  content: "\ea0b";
+}
+
+.nc-basket::before {
+  content: "\ea0c";
+}
+
+.nc-bell-55::before {
+  content: "\ea0d";
+}
+
+.nc-bold::before {
+  content: "\ea0e";
+}
+
+.nc-book-bookmark::before {
+  content: "\ea0f";
+}
+
+.nc-bookmark-2::before {
+  content: "\ea10";
+}
+
+.nc-box-2::before {
+  content: "\ea11";
+}
+
+.nc-box::before {
+  content: "\ea12";
+}
+
+.nc-briefcase-24::before {
+  content: "\ea13";
+}
+
+.nc-bulb-63::before {
+  content: "\ea14";
+}
+
+.nc-bullet-list-67::before {
+  content: "\ea15";
+}
+
+.nc-bus-front-12::before {
+  content: "\ea16";
+}
+
+.nc-button-pause::before {
+  content: "\ea17";
+}
+
+.nc-button-play::before {
+  content: "\ea18";
+}
+
+.nc-button-power::before {
+  content: "\ea19";
+}
+
+.nc-calendar-60::before {
+  content: "\ea1a";
+}
+
+.nc-camera-compact::before {
+  content: "\ea1b";
+}
+
+.nc-caps-small::before {
+  content: "\ea1c";
+}
+
+.nc-cart-simple::before {
+  content: "\ea1d";
+}
+
+.nc-chart-bar-32::before {
+  content: "\ea1e";
+}
+
+.nc-chart-pie-36::before {
+  content: "\ea1f";
+}
+
+.nc-chat-33::before {
+  content: "\ea20";
+}
+
+.nc-check-2::before {
+  content: "\ea21";
+}
+
+.nc-circle-10::before {
+  content: "\ea22";
+}
+
+.nc-cloud-download-93::before {
+  content: "\ea23";
+}
+
+.nc-cloud-upload-94::before {
+  content: "\ea24";
+}
+
+.nc-compass-05::before {
+  content: "\ea25";
+}
+
+.nc-controller-modern::before {
+  content: "\ea26";
+}
+
+.nc-credit-card::before {
+  content: "\ea27";
+}
+
+.nc-delivery-fast::before {
+  content: "\ea28";
+}
+
+.nc-diamond::before {
+  content: "\ea29";
+}
+
+.nc-email-85::before {
+  content: "\ea2a";
+}
+
+.nc-favourite-28::before {
+  content: "\ea2b";
+}
+
+.nc-glasses-2::before {
+  content: "\ea2c";
+}
+
+.nc-globe-2::before {
+  content: "\ea2d";
+}
+
+.nc-globe::before {
+  content: "\ea2e";
+}
+
+.nc-hat-3::before {
+  content: "\ea2f";
+}
+
+.nc-headphones::before {
+  content: "\ea30";
+}
+
+.nc-html5::before {
+  content: "\ea31";
+}
+
+.nc-image::before {
+  content: "\ea32";
+}
+
+.nc-istanbul::before {
+  content: "\ea33";
+}
+
+.nc-key-25::before {
+  content: "\ea34";
+}
+
+.nc-laptop::before {
+  content: "\ea35";
+}
+
+.nc-layout-11::before {
+  content: "\ea36";
+}
+
+.nc-lock-circle-open::before {
+  content: "\ea37";
+}
+
+.nc-map-big::before {
+  content: "\ea38";
+}
+
+.nc-minimal-down::before {
+  content: "\ea39";
+}
+
+.nc-minimal-left::before {
+  content: "\ea3a";
+}
+
+.nc-minimal-right::before {
+  content: "\ea3b";
+}
+
+.nc-minimal-up::before {
+  content: "\ea3c";
+}
+
+.nc-mobile::before {
+  content: "\ea3d";
+}
+
+.nc-money-coins::before {
+  content: "\ea3e";
+}
+
+.nc-note-03::before {
+  content: "\ea3f";
+}
+
+.nc-palette::before {
+  content: "\ea40";
+}
+
+.nc-paper::before {
+  content: "\ea41";
+}
+
+.nc-pin-3::before {
+  content: "\ea42";
+}
+
+.nc-planet::before {
+  content: "\ea43";
+}
+
+.nc-refresh-69::before {
+  content: "\ea44";
+}
+
+.nc-ruler-pencil::before {
+  content: "\ea45";
+}
+
+.nc-satisfied::before {
+  content: "\ea46";
+}
+
+.nc-scissors::before {
+  content: "\ea47";
+}
+
+.nc-send::before {
+  content: "\ea48";
+}
+
+.nc-settings-gear-65::before {
+  content: "\ea49";
+}
+
+.nc-settings::before {
+  content: "\ea4a";
+}
+
+.nc-share-66::before {
+  content: "\ea4b";
+}
+
+.nc-shop::before {
+  content: "\ea4c";
+}
+
+.nc-simple-add::before {
+  content: "\ea4d";
+}
+
+.nc-simple-delete::before {
+  content: "\ea4e";
+}
+
+.nc-simple-remove::before {
+  content: "\ea4f";
+}
+
+.nc-single-02::before {
+  content: "\ea50";
+}
+
+.nc-single-copy-04::before {
+  content: "\ea51";
+}
+
+.nc-sound-wave::before {
+  content: "\ea52";
+}
+
+.nc-spaceship::before {
+  content: "\ea53";
+}
+
+.nc-sun-fog-29::before {
+  content: "\ea54";
+}
+
+.nc-support-17::before {
+  content: "\ea55";
+}
+
+.nc-tablet-2::before {
+  content: "\ea56";
+}
+
+.nc-tag-content::before {
+  content: "\ea57";
+}
+
+.nc-tap-01::before {
+  content: "\ea58";
+}
+
+.nc-tie-bow::before {
+  content: "\ea59";
+}
+
+.nc-tile-56::before {
+  content: "\ea5a";
+}
+
+.nc-time-alarm::before {
+  content: "\ea5b";
+}
+
+.nc-touch-id::before {
+  content: "\ea5c";
+}
+
+.nc-trophy::before {
+  content: "\ea5d";
+}
+
+.nc-tv-2::before {
+  content: "\ea5e";
+}
+
+.nc-umbrella-13::before {
+  content: "\ea5f";
+}
+
+.nc-user-run::before {
+  content: "\ea60";
+}
+
+.nc-vector::before {
+  content: "\ea61";
+}
+
+.nc-watch-time::before {
+  content: "\ea62";
+}
+
+.nc-world-2::before {
+  content: "\ea63";
+}
+
+.nc-zoom-split::before {
+  content: "\ea64";
+}
+
+/* all icon font classes list here */
+
+.btn-twitter {
+  color: #55acee !important;
+}
+
+.btn-twitter:hover,
+.btn-twitter:focus,
+.btn-twitter:active {
+  color: #55acee !important;
+}
+
+.btn-facebook {
+  color: #3b5998 !important;
+}
+
+.btn-facebook:hover,
+.btn-facebook:focus,
+.btn-facebook:active {
+  color: #3b5998 !important;
+}
+
+.btn-google {
+  color: #dd4b39 !important;
+}
+
+.btn-google:hover,
+.btn-google:focus,
+.btn-google:active {
+  color: #dd4b39 !important;
+}
+
+.btn-linkedin {
+  color: #0976b4 !important;
+}
+
+.btn-linkedin:hover,
+.btn-linkedin:focus,
+.btn-linkedin:active {
+  color: #0976b4 !important;
+}
+
+.btn-twitter-bg {
+  background-color: #55acee !important;
+  border-color: #55acee !important;
+}
+
+.btn-twitter-bg:hover {
+  background-color: #3ea1ec !important;
+  border-color: #3ea1ec !important;
+}
+
+.btn-facebook-bg {
+  background-color: #3b5998 !important;
+  border-color: #3b5998 !important;
+}
+
+.btn-facebook-bg:hover {
+  background-color: #344e86 !important;
+  border-color: #344e86 !important;
+}
+
+.btn-google-bg {
+  background-color: #dd4b39 !important;
+  border-color: #dd4b39 !important;
+}
+
+.btn-google-bg:hover {
+  background-color: #d73925 !important;
+  border-color: #d73925 !important;
+}
+
+.btn-github-bg {
+  background-color: #767676 !important;
+  border-color: #767676 !important;
+}
+
+.btn-github-bg:hover {
+  background-color: dimgray !important;
+  border-color: dimgray !important;
+}
+
+/*             Navigation menu                */
+
+/*             Navigation Tabs                 */
+
+.nav-tabs-navigation {
+  text-align: center;
+  border-bottom: 1px solid #F1EAE0;
+  margin-bottom: 30px;
+}
+
+.nav-tabs-navigation .nav>.nav-item>.nav-link {
+  padding-bottom: 20px;
+}
+
+.nav-tabs-wrapper {
+  display: inline-block;
+  margin-bottom: -6px;
+  margin-left: 1.25%;
+  margin-right: 1.25%;
+  position: relative;
+  width: auto;
+}
+
+.nav-tabs {
+  border-bottom: 0 none;
+  font-size: 16px;
+  font-weight: 600;
+}
+
+.nav-tabs .nav-item .nav-link {
+  border: 0 none;
+  color: #A49E93;
+  background-color: transparent;
+}
+
+.nav-tabs .nav-item .nav-link:hover {
+  color: #66615b;
+}
+
+.nav-tabs .nav-item .nav-link.active {
+  color: #66615b;
+}
+
+.nav-tabs .nav-item {
+  color: #66615b;
+  position: relative;
+}
+
+.nav-tabs .nav-item .nav-link.active,
+.nav-tabs .nav-item .nav-link.active:hover,
+.nav-tabs .nav-item .nav-link.active:focus {
+  background-color: transparent;
+  border: 0 none;
+}
+
+.nav-tabs .nav-item .nav-link.active:after,
+.nav-tabs .nav-item .nav-link.active:hover:after,
+.nav-tabs .nav-item .nav-link.active:focus:after {
+  border-bottom: 11px solid #FFFFFF;
+  border-left: 11px solid transparent;
+  border-right: 11px solid transparent;
+  content: "";
+  display: inline-block;
+  position: absolute;
+  right: 40%;
+  bottom: 5px;
+}
+
+.nav-tabs .nav-item .nav-link.active:before,
+.nav-tabs .nav-item .nav-link.active:hover:before,
+.nav-tabs .nav-item .nav-link.active:focus:before {
+  border-bottom: 11px solid #F1EAE0;
+  border-left: 11px solid transparent;
+  border-right: 11px solid transparent;
+  content: "";
+  display: inline-block;
+  position: absolute;
+  right: 40%;
+  bottom: 6px;
+}
+
+.nav-tabs .nav-item.show .nav-link {
+  background-color: transparent;
+}
+
+.nav-tabs .dropdown-menu {
+  margin-top: -6px;
+  margin-left: -46px;
+  border-radius: 8px;
+}
+
+.nav-tabs .dropdown-menu .dropdown-item:hover,
+.nav-tabs .dropdown-menu .dropdown-item.active {
+  color: #FFFFFF;
+  background-color: #68B3C8;
+}
+
+.nav-tabs .dropdown-menu :before {
+  border-bottom: 11px solid #F1EAE0;
+  border-left: 11px solid transparent;
+  border-right: 11px solid transparent;
+  content: "";
+  display: inline-block;
+  position: absolute;
+  right: 12px;
+  top: -11px;
+}
+
+.nav-tabs .dropdown-menu :after {
+  border-bottom: 11px solid #FFFCF5;
+  border-left: 11px solid transparent;
+  border-right: 11px solid transparent;
+  content: "";
+  display: inline-block;
+  position: absolute;
+  right: 12px;
+  top: -10px;
+}
+
+.profile-content .tab-content .tab-pane {
+  min-height: 200px;
+}
+
+.profile-content .tab-content #tweets,
+.profile-content .tab-content #connections,
+.profile-content .tab-content #media {
+  height: 100%;
+}
+
+/*             Navigation Pills               */
+
+.nav-pills .nav-item+.nav-link {
+  margin-left: 0;
+}
+
+.nav-pills .nav-item .nav-link {
+  border: 1px solid #66615B;
+  border-radius: 0;
+  color: #66615B;
+  font-weight: 600;
+  margin-left: -1px;
+  padding: 10px 25px;
+}
+
+.nav-pills .nav-item.active .nav-link,
+.nav-pills .nav-item.active .nav-link:hover,
+.nav-pills .nav-item.active .nav-link:focus {
+  background-color: #66615B;
+  color: #FFFFFF;
+}
+
+.nav-pills .nav-item:first-child .nav-link {
+  border-radius: 30px 0 0 30px !important;
+  margin: 0;
+}
+
+.nav-pills .nav-item:last-child .nav-link {
+  border-radius: 0 30px 30px 0 !important;
+}
+
+.nav-pills .nav-item .nav-link.active {
+  background-color: #66615B;
+  color: #FFFFFF;
+}
+
+.nav-pills-primary .nav-item .nav-link {
+  border: 1px solid #51cbce !important;
+  color: #51cbce !important;
+}
+
+.nav-pills-primary .nav-item .nav-link.active {
+  border: 1px solid #51cbce !important;
+  color: #FFFFFF !important;
+}
+
+.nav-pills-danger .nav-item .nav-link {
+  border: 1px solid #f5593d !important;
+  color: #f5593d !important;
+}
+
+.nav-pills-danger .nav-item .nav-link.active {
+  border: 1px solid #f5593d !important;
+  color: #FFFFFF !important;
+}
+
+.nav-pills-info .nav-item .nav-link {
+  border: 1px solid #51bcda !important;
+  color: #51bcda !important;
+}
+
+.nav-pills-info .nav-item .nav-link.active {
+  border: 1px solid #51bcda !important;
+  color: #FFFFFF !important;
+}
+
+.nav-pills-success .nav-item .nav-link {
+  border: 1px solid #6bd098 !important;
+  color: #6bd098 !important;
+}
+
+.nav-pills-success .nav-item .nav-link.active {
+  border: 1px solid #6bd098 !important;
+  color: #FFFFFF !important;
+}
+
+.nav-pills-warning .nav-item .nav-link {
+  border: 1px solid #fbc658 !important;
+  color: #fbc658 !important;
+}
+
+.nav-pills-warning .nav-item .nav-link.active {
+  border: 1px solid #fbc658 !important;
+  color: #FFFFFF !important;
+}
+
+.nav .nav-item .nav-link:hover,
+.nav .nav-item .nav-link:focus {
+  background-color: transparent;
+}
+
+.navbar {
+  border: 0;
+  font-size: 14px;
+  transition: all 0.4s;
+  -webkit-transition: all 0.4s;
+  padding: 0;
+  background: #FFFFFF;
+  box-shadow: 0 6px 10px -4px rgba(0, 0, 0, 0.15);
+}
+
+.navbar .navbar-brand {
+  font-weight: 600;
+  margin: 5px 0px;
+  padding: 20px 15px;
+  font-size: 14px;
+  color: #66615B;
+  text-transform: uppercase;
+}
+
+.navbar .navbar-toggler:focus {
+  outline: none;
+}
+
+.navbar .form-control-feedback {
+  padding-left: 0px;
+}
+
+.navbar:not([class*="bg"]) .navbar-toggler .navbar-toggler-bar {
+  background: #66615B !important;
+}
+
+.navbar .navbar-nav .nav-item .nav-link {
+  line-height: 1.6;
+  margin: 15px 3px;
+  padding: 10px 15px;
+  opacity: .8;
+  font-size: 12px;
+  text-transform: uppercase;
+  font-weight: 600;
+  color: #66615B;
+}
+
+.navbar .navbar-nav .nav-item .nav-link p {
+  margin: 0px 0px;
+  text-transform: uppercase;
+  font-weight: 600;
+  font-size: 12px;
+  line-height: 1.5em;
+  padding: 15px 0;
+}
+
+.navbar .navbar-nav .nav-item .nav-link.btn {
+  margin: 15px 3px;
+  padding: 9px;
+}
+
+.navbar .navbar-nav .nav-item .nav-link [class^="fa"] {
+  font-size: 17px;
+  position: relative;
+  right: 5px;
+}
+
+.navbar .navbar-nav .dropdown-menu {
+  border-radius: 12px;
+  margin-top: 1px;
+}
+
+.navbar .navbar-nav .nav-item .btn i {
+  color: #FFFFFF;
+}
+
+.navbar .navbar-collapse .nav-item .nav-link p {
+  display: inline;
+}
+
+.navbar .navbar-collapse .nav-item .dropdown-item i {
+  margin: 0 10px;
+  margin: 0 10px 0px 5px;
+  font-size: 18px;
+  position: relative;
+  top: 3px;
+}
+
+.navbar .navbar-collapse.show .navbar-nav .nav-item {
+  padding-right: 10px;
+}
+
+.navbar .navbar-collapse:after {
+  background-color: #FFFCF5;
+}
+
+.navbar #navbarSupportedContent .nav-item {
+  position: relative;
+}
+
+.navbar .notification-bubble {
+  padding: 0.4em 0.6em;
+  position: absolute;
+  top: 10px;
+  right: -2px;
+}
+
+.navbar .btn {
+  margin: 14px 3px;
+  font-size: 12px;
+}
+
+.navbar .btn i {
+  font-size: 14px;
+  position: relative;
+  top: 2px;
+}
+
+.navbar .btn-simple {
+  font-size: 16px;
+}
+
+.navbar .caret {
+  left: 0;
+  right: 0;
+  margin-right: auto;
+  margin-left: auto;
+  position: absolute;
+}
+
+.navbar.navbar-transparent {
+  background: transparent !important;
+  padding-top: 25px;
+  box-shadow: none;
+}
+
+.navbar.navbar-transparent .navbar-brand {
+  color: #FFFFFF;
+}
+
+.navbar.navbar-transparent .navbar-nav .nav-item .nav-link {
+  color: #FFFFFF;
+}
+
+.navbar.navbar-transparent .navbar-toggler .navbar-toggler-bar {
+  background: #FFFFFF !important;
+}
+
+.navbar .logo-container {
+  margin-top: 5px;
+}
+
+.navbar .logo-container .logo {
+  overflow: hidden;
+  border-radius: 50%;
+  border: 1px solid #333333;
+  width: 50px;
+  float: left;
+}
+
+.navbar .logo-container .logo img {
+  width: 100%;
+}
+
+.navbar .logo-container .brand {
+  font-size: 18px;
+  color: #FFFFFF;
+  line-height: 20px;
+  float: left;
+  margin-left: 10px;
+  margin-top: 5px;
+  width: 75px;
+  height: 50px;
+}
+
+.navbar .navbar-toggler .navbar-toggler-bar+.navbar-toggler-bar,
+.navbar .navbar-toggler .navbar-toggler-icon+.navbar-toggler-icon {
+  margin-top: 4px;
+}
+
+.navbar .navbar-toggler .navbar-toggler-bar {
+  background: #FFFFFF !important;
+  display: block;
+  position: relative;
+  width: 24px;
+  height: 2px;
+  border-radius: 1px;
+  margin: 0 auto;
+}
+
+.navbar-transparent .navbar-brand,
+[class*="bg"] .navbar-brand {
+  color: #FFFFFF;
+  opacity: 0.9;
+  filter: alpha(opacity=90);
+}
+
+.navbar-transparent .navbar-brand:focus,
+.navbar-transparent .navbar-brand:hover,
+[class*="bg"] .navbar-brand:focus,
+[class*="bg"] .navbar-brand:hover {
+  background-color: transparent;
+  opacity: 1;
+  filter: alpha(opacity=100);
+  color: #FFFFFF;
+}
+
+.navbar-transparent .navbar-nav .nav-item .nav-link:not(.btn),
+[class*="bg"] .navbar-nav .nav-item .nav-link:not(.btn) {
+  color: #FFFFFF;
+  border-color: #FFFFFF;
+}
+
+.navbar-transparent .navbar-nav .active .nav-link .active .nav-link:hover,
+.navbar-transparent .navbar-nav .active .nav-link:focus,
+.navbar-transparent .navbar-nav .nav-item .nav-link:hover,
+.navbar-transparent .navbar-nav .nav-item .nav-link:focus,
+[class*="bg"] .navbar-nav .active .nav-link .active .nav-link:hover,
+[class*="bg"] .navbar-nav .active .nav-link:focus,
+[class*="bg"] .navbar-nav .nav-item .nav-link:hover,
+[class*="bg"] .navbar-nav .nav-item .nav-link:focus {
+  background-color: transparent;
+  color: #FFFFFF;
+  opacity: 1;
+  filter: alpha(opacity=100);
+}
+
+.navbar-transparent .navbar-nav .nav .nav-item a.btn:hover,
+[class*="bg"] .navbar-nav .nav .nav-item a.btn:hover {
+  background-color: transparent;
+}
+
+.navbar-transparent .navbar-nav .dropdown .nav-link .caret,
+.navbar-transparent .navbar-nav .dropdown .nav-link:hover .caret,
+.navbar-transparent .navbar-nav .dropdown .nav-link:focus .caret,
+[class*="bg"] .navbar-nav .dropdown .nav-link .caret,
+[class*="bg"] .navbar-nav .dropdown .nav-link:hover .caret,
+[class*="bg"] .navbar-nav .dropdown .nav-link:focus .caret {
+  border-bottom-color: #FFFFFF;
+  border-top-color: #FFFFFF;
+}
+
+.navbar-transparent .navbar-nav .open .nav-link,
+.navbar-transparent .navbar-nav .open .nav-link:hover,
+.navbar-transparent .navbar-nav .open .nav-link:focus,
+[class*="bg"] .navbar-nav .open .nav-link,
+[class*="bg"] .navbar-nav .open .nav-link:hover,
+[class*="bg"] .navbar-nav .open .nav-link:focus {
+  background-color: transparent;
+  color: #66615B;
+  opacity: 1;
+  filter: alpha(opacity=100);
+}
+
+.navbar-transparent .btn-default.btn-fill,
+[class*="bg"] .btn-default.btn-fill {
+  color: #9A9A9A;
+  background-color: #FFFFFF;
+  opacity: 0.9;
+  filter: alpha(opacity=90);
+}
+
+.navbar-transparent .btn-default.btn-fill:hover,
+.navbar-transparent .btn-default.btn-fill:focus,
+.navbar-transparent .btn-default.btn-fill:active,
+.navbar-transparent .btn-default.btn-fill.active,
+.navbar-transparent .open .dropdown-toggle.btn-fill.btn-default,
+[class*="bg"] .btn-default.btn-fill:hover,
+[class*="bg"] .btn-default.btn-fill:focus,
+[class*="bg"] .btn-default.btn-fill:active,
+[class*="bg"] .btn-default.btn-fill.active,
+[class*="bg"] .open .dropdown-toggle.btn-fill.btn-default {
+  border-color: #FFFFFF;
+  opacity: 1;
+  filter: alpha(opacity=100);
+}
+
+.navbar-absolute {
+  position: absolute;
+  width: 100%;
+  padding-top: 10px;
+  z-index: 1029;
+}
+
+.bd-docs .navigation-example .navbar.navbar-transparent {
+  padding-top: 0;
+  padding: 20px 0;
+  margin-top: 20px;
+}
+
+.dropdown>.dropdown-menu:first-of-type {
+  display: block;
+  transition: all 0.3s cubic-bezier(0.215, 0.61, 0.355, 1) 0s, opacity 0.3s ease 0s, height 0s linear 0.35s;
+}
+
+.dropdown .dropdown-menu {
+  opacity: 0;
+  filter: alpha(opacity=0);
+  -webkit-box-shadow: 0 2px rgba(17, 16, 15, 0.1), 0 2px 10px rgba(17, 16, 15, 0.1);
+  box-shadow: 0 2px rgba(17, 16, 15, 0.1), 0 2px 10px rgba(17, 16, 15, 0.1);
+  visibility: hidden;
+  position: absolute;
+}
+
+.dropdown .dropdown-menu[x-placement="top-start"] {
+  -webkit-transform: translate3d(0, 0px, 0) !important;
+  -moz-transform: translate3d(0, 0px, 0) !important;
+  -o-transform: translate3d(0, 0px, 0) !important;
+  -ms-transform: translate3d(0, 0px, 0) !important;
+  transform: translate3d(0, 0px, 0) !important;
+}
+
+.dropdown .dropdown-menu[x-placement="bottom-start"] {
+  -webkit-transform: translate3d(0, 0px, 0) !important;
+  -moz-transform: translate3d(0, 0px, 0) !important;
+  -o-transform: translate3d(0, 0px, 0) !important;
+  -ms-transform: translate3d(0, 0px, 0) !important;
+  transform: translate3d(0, 0px, 0) !important;
+}
+
+.dropdown.show .dropdown-menu {
+  opacity: 1;
+  filter: alpha(opacity=100);
+  visibility: visible;
+}
+
+.dropdown.show .dropdown-menu[x-placement="top-start"] {
+  -webkit-transform: translate3d(0, -50px, 0) !important;
+  -moz-transform: translate3d(0, -50px, 0) !important;
+  -o-transform: translate3d(0, -50px, 0) !important;
+  -ms-transform: translate3d(0, -50px, 0) !important;
+  transform: translate3d(0, -50px, 0) !important;
+  top: auto !important;
+  bottom: 0 !important;
+}
+
+.dropdown.show .dropdown-menu[x-placement="bottom-start"] {
+  -webkit-transform: translate3d(0, 40px, 0) !important;
+  -moz-transform: translate3d(0, 40px, 0) !important;
+  -o-transform: translate3d(0, 40px, 0) !important;
+  -ms-transform: translate3d(0, 40px, 0) !important;
+  transform: translate3d(0, 40px, 0) !important;
+  bottom: auto !important;
+  top: 0 !important;
+}
+
+.dropdown-menu {
+  background-color: #FFFFFF;
+  border: 0 none;
+  border-radius: 12px;
+  margin-top: 10px;
+  padding: 0px;
+}
+
+.dropdown-menu .divider {
+  background-color: #F1EAE0;
+  margin: 0px;
+}
+
+.dropdown-menu .dropdown-header {
+  color: #9A9A9A;
+  font-size: 12px;
+  padding: 10px 15px;
+}
+
+.dropdown-menu .no-notification {
+  color: #9A9A9A;
+  font-size: 1.2em;
+  padding: 30px 30px;
+  text-align: center;
+}
+
+.dropdown-menu .dropdown-item {
+  color: #66615b;
+  font-size: 14px;
+  padding: 10px 45px 10px 15px;
+  clear: both;
+  white-space: nowrap;
+  width: 100%;
+  display: block;
+}
+
+.dropdown-menu .dropdown-item img {
+  margin-top: -3px;
+}
+
+.dropdown-menu .dropdown-item:focus {
+  outline: 0 !important;
+}
+
+.btn-group.select .dropdown-menu {
+  min-width: 100%;
+}
+
+.dropdown-menu .dropdown-item:first-child {
+  border-top-left-radius: 12px;
+  border-top-right-radius: 12px;
+}
+
+.dropdown-menu .dropdown-item:last-child {
+  border-bottom-left-radius: 12px;
+  border-bottom-right-radius: 12px;
+}
+
+.dropdown-menu .dropdown-item.dropdown-toggle:last-of-type {
+  border-bottom-left-radius: 12px;
+  border-bottom-right-radius: 12px;
+}
+
+.dropdown-menu .dropdown-item.dropdown-toggle:last-of-type+.dropdown-menu.show {
+  left: 100% !important;
+}
+
+.dropdown-menu .dropdown-item.dropdown-toggle:last-of-type+.dropdown-menu .dropdown-item.dropdown-toggle {
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
+}
+
+.dropdown-menu .dropdown-item.dropdown-toggle:last-of-type+.dropdown-menu li .dropdown-item.dropdown-toggle {
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+  border-bottom-left-radius: 12px;
+  border-bottom-right-radius: 12px;
+}
+
+.select .dropdown-menu .dropdown-item:first-child {
+  border-radius: 0;
+  border-bottom: 0 none;
+}
+
+.dropdown-menu .dropdown-item:hover,
+.dropdown-menu .dropdown-item:focus {
+  color: #FFFFFF !important;
+  opacity: 1;
+  text-decoration: none;
+}
+
+.dropdown-menu .dropdown-item:hover,
+.dropdown-menu .dropdown-item:focus {
+  background-color: #66615B;
+}
+
+.dropdown-menu.dropdown-primary .dropdown-item:hover,
+.dropdown-menu.dropdown-primary .dropdown-item:focus {
+  background-color: #6dd3d6;
+}
+
+.dropdown-menu.dropdown-info .dropdown-item:hover,
+.dropdown-menu.dropdown-info .dropdown-item:focus {
+  background-color: #6ec7e0;
+}
+
+.dropdown-menu.dropdown-success .dropdown-item:hover,
+.dropdown-menu.dropdown-success .dropdown-item:focus {
+  background-color: #86d9ab;
+}
+
+.dropdown-menu.dropdown-warning .dropdown-item:hover,
+.dropdown-menu.dropdown-warning .dropdown-item:focus {
+  background-color: #fcd27b;
+}
+
+.dropdown-menu.dropdown-danger .dropdown-item:hover,
+.dropdown-menu.dropdown-danger .dropdown-item:focus {
+  background-color: #f7765f;
+}
+
+.dropdown-divider {
+  margin: 0 !important;
+}
+
+.btn-group.select.open {
+  overflow: visible;
+}
+
+.dropdown-menu-right {
+  right: -2px;
+  left: auto;
+}
+
+.alert {
+  border: 0;
+  border-radius: 0;
+  color: #FFFFFF;
+  padding: 10px 15px;
+  font-size: 14px;
+}
+
+.alert .close {
+  font-size: 20px;
+  color: #FFFFFF;
+}
+
+.container .alert {
+  border-radius: 4px;
+}
+
+.navbar .alert {
+  border-radius: 0;
+  left: 0;
+  position: absolute;
+  right: 0;
+  top: 85px;
+  width: 100%;
+  z-index: 3;
+}
+
+.navbar:not(.navbar-transparent) .alert {
+  top: 70px;
+}
+
+.alert .alert-icon {
+  display: block;
+  font-size: 30px;
+  left: 15px;
+  position: absolute;
+  top: 50%;
+  margin-top: -22px;
+}
+
+.alert .alert-wrapper.message {
+  padding-right: 60px;
+}
+
+.alert .alert-wrapper i {
+  position: relative;
+  font-size: 20px;
+  top: 5px;
+  margin-top: -5px;
+  font-weight: 600;
+}
+
+.alert-info {
+  background-color: #6ec7e0;
+}
+
+.alert-success {
+  background-color: #86d9ab;
+}
+
+.alert-warning {
+  background-color: #fcd27b;
+}
+
+.alert-danger {
+  background-color: #f7765f;
+}
+
+.img-rounded {
+  border-radius: 12px;
+  transition: opacity 0.5s ease 0s;
+  max-width: 100%;
+}
+
+.img-details {
+  min-height: 50px;
+  padding: 0 4px 0.5em;
+}
+
+.img-details img {
+  width: 50px;
+}
+
+.img-details .author {
+  margin-left: 10px;
+  margin-top: -21px;
+  width: 40px;
+}
+
+.img-circle {
+  background-color: #FFFFFF;
+  margin-bottom: 10px;
+  padding: 4px;
+  border-radius: 50% !important;
+  max-width: 100%;
+}
+
+.img-thumbnail {
+  border: 0 none;
+  border-radius: 12px;
+  box-shadow: 0 1px 2px rgba(164, 158, 147, 0.6);
+  margin-bottom: 10px;
+}
+
+.img-no-padding {
+  padding: 0px;
+}
+
+.example-page .img-rounded {
+  margin: 50px 0 20px;
+}
+
+.img-shadow {
+  box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.2);
+}
+
+.images-title {
+  margin-bottom: 20px;
+  height: 50px;
+}
+
+.nav-link .profile-photo-small {
+  width: 40px;
+  height: 30px;
+  margin: -10px 0 0 -15px;
+}
+
+.profile-picture {
+  margin: 0 auto;
+}
+
+.profile-picture .fileinput-new img {
+  width: 150px;
+  height: 150px;
+  border-radius: 50%;
+  margin-bottom: 10px;
+}
+
+.profile-picture .fileinput-exists img {
+  max-width: 150px;
+  max-height: 150px;
+  border-radius: 50%;
+  margin-bottom: 10px;
+}
+
+.tooltip {
+  font-size: 12px;
+  font-weight: 400;
+}
+
+.tooltip-inner {
+  background-color: #FFFFFF;
+  border-radius: 4px;
+  box-shadow: 0 1px 13px rgba(0, 0, 0, 0.14), 0 0 0 1px rgba(115, 71, 38, 0.23);
+  color: #66615B;
+  max-width: 200px;
+  padding: 10px 10px;
+  text-align: center;
+  text-decoration: none;
+}
+
+.tooltip-inner:after {
+  content: "";
+  display: inline-block;
+  position: absolute;
+}
+
+.tooltip-inner:before {
+  content: "";
+  display: inline-block;
+  position: absolute;
+}
+
+.tooltip.fade.bs-tooltip-left,
+.tooltip.fade.bs-tooltip-left.show {
+  left: -5px !important;
+}
+
+.tooltip.fade.bs-tooltip-left .arrow,
+.tooltip.fade.bs-tooltip-left.show .arrow {
+  border-left: 11px solid rgba(0, 0, 0, 0.2);
+  border-top: 11px solid transparent;
+  border-bottom: 11px solid transparent;
+  right: -6px;
+  left: auto;
+  margin-left: 0;
+  top: -8px;
+}
+
+.tooltip.fade.bs-tooltip-left .arrow::before,
+.tooltip.fade.bs-tooltip-left.show .arrow::before {
+  border-left: 11px solid #FFFFFF;
+  border-top: 11px solid transparent;
+  border-bottom: 11px solid transparent;
+  right: 1px;
+  left: auto;
+  margin-left: 0;
+  top: -8px;
+}
+
+.tooltip.fade.bs-tooltip-right,
+.tooltip.fade.bs-tooltip-right.show {
+  left: 6px !important;
+}
+
+.tooltip.fade.bs-tooltip-right .arrow,
+.tooltip.fade.bs-tooltip-right.show .arrow {
+  border-right: 11px solid rgba(0, 0, 0, 0.2);
+  border-top: 11px solid transparent;
+  border-bottom: 11px solid transparent;
+  left: -6px;
+  right: auto;
+  margin-right: 0;
+  top: -8px;
+}
+
+.tooltip.fade.bs-tooltip-right .arrow::before,
+.tooltip.fade.bs-tooltip-right.show .arrow::before {
+  border-right: 11px solid #FFFFFF;
+  border-top: 11px solid transparent;
+  border-bottom: 11px solid transparent;
+  left: 1px;
+  right: auto;
+  margin-right: 0;
+  top: -8px;
+}
+
+.tooltip.fade.bs-tooltip-top,
+.tooltip.fade.bs-tooltip-top.show {
+  top: -6px !important;
+}
+
+.tooltip.fade.bs-tooltip-top .arrow,
+.tooltip.fade.bs-tooltip-top.show .arrow {
+  border-top: 11px solid rgba(0, 0, 0, 0.2);
+  border-left: 11px solid transparent;
+  border-right: 11px solid transparent;
+  right: auto;
+  margin-right: 0;
+  top: 43px;
+}
+
+.tooltip.fade.bs-tooltip-top .arrow::before,
+.tooltip.fade.bs-tooltip-top.show .arrow::before {
+  border-top: 11px solid #FFFFFF;
+  border-left: 11px solid transparent;
+  border-right: 11px solid transparent;
+  left: -8px;
+  right: auto;
+  top: -12px;
+}
+
+.tooltip.fade.bs-tooltip-bottom,
+.tooltip.fade.bs-tooltip-bottom.show {
+  top: 6px !important;
+}
+
+.tooltip.fade.bs-tooltip-bottom .arrow,
+.tooltip.fade.bs-tooltip-bottom.show .arrow {
+  border-bottom: 11px solid rgba(0, 0, 0, 0.2);
+  border-left: 11px solid transparent;
+  border-right: 11px solid transparent;
+  right: auto;
+  margin-right: 0;
+  top: -6px;
+}
+
+.tooltip.fade.bs-tooltip-bottom .arrow::before,
+.tooltip.fade.bs-tooltip-bottom.show .arrow::before {
+  border-bottom: 11px solid #FFFFFF;
+  border-left: 11px solid transparent;
+  border-right: 11px solid transparent;
+  left: -8px;
+  right: auto;
+  top: 1px;
+}
+
+.tooltip.show {
+  opacity: 1 !important;
+}
+
+.popover {
+  border: 0;
+  border-radius: 4px;
+  background-color: #FFFFFF;
+  color: #66615b;
+  font-weight: 400;
+  padding: 0;
+  z-index: 1031;
+  -webkit-box-shadow: none;
+  box-shadow: none;
+  text-align: center;
+}
+
+.popover-header {
+  background-color: #FFFCF5;
+  border-bottom: 0 none;
+  font-size: 15px;
+  font-weight: normal;
+  line-height: 22px;
+  padding: 15px 15px 0px 15px;
+  margin: 0;
+  color: #66615b;
+  text-align: center;
+  border-radius: 4px 4px 0 0;
+  margin-bottom: -10px;
+}
+
+.popover-header {
+  background-color: #FFFFFF !important;
+  text-align: center;
+}
+
+.popover-body {
+  padding: 15px;
+  text-align: center;
+}
+
+.popover .arrow {
+  border: 0;
+}
+
+.popover.top .arrow {
+  margin-left: 0;
+}
+
+.popover.bottom .arrow:after {
+  border-bottom-color: #f7765f;
+}
+
+.popover-filter {
+  position: fixed;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 1030;
+  background-color: #000000;
+  opacity: 0;
+  filter: alpha(opacity=0);
+  visibility: hidden;
+  transition: visibility 0s linear 0.3s, opacity 0.3s linear;
+}
+
+.popover-filter.in {
+  visibility: visible;
+  opacity: 0.2;
+  filter: alpha(opacity=20);
+  transition-delay: 0s;
+}
+
+.popover.left>.arrow::after {
+  border-left-color: #f7765f;
+  bottom: -20px;
+}
+
+.popover.top>.arrow::after {
+  border-top-color: #f7765f;
+}
+
+.popover.right>.arrow::after {
+  border-right-color: #f7765f;
+}
+
+.popover.left::before {
+  border-left-color: #f7765f;
+  bottom: -20px;
+}
+
+.popover-filter.in {
+  visibility: visible;
+  opacity: 0.2;
+  filter: alpha(opacity=20);
+  transition-delay: 0s;
+}
+
+.popover-primary {
+  background-color: #6dd3d6;
+  color: #FFFFFF;
+}
+
+.popover-primary .popover-title {
+  background-color: #6dd3d6;
+  color: rgba(0, 0, 0, 0.56);
+}
+
+.popover-primary.bottom .arrow:after {
+  border-bottom-color: #6dd3d6;
+}
+
+.popover-primary.left>.arrow::after {
+  border-left-color: #6dd3d6;
+}
+
+.popover-primary.top>.arrow::after {
+  border-top-color: #6dd3d6;
+}
+
+.popover-primary.right>.arrow::after {
+  border-right-color: #6dd3d6;
+}
+
+.popover-info {
+  background-color: #6ec7e0;
+  color: #FFFFFF;
+}
+
+.popover-info .popover-title {
+  background-color: #6ec7e0;
+  color: rgba(0, 0, 0, 0.56);
+}
+
+.popover-info.bottom .arrow:after {
+  border-bottom-color: #6ec7e0;
+}
+
+.popover-info.left>.arrow::after {
+  border-left-color: #6ec7e0;
+}
+
+.popover-info.top>.arrow::after {
+  border-top-color: #6ec7e0;
+}
+
+.popover-info.right>.arrow::after {
+  border-right-color: #6ec7e0;
+}
+
+.popover-success {
+  background-color: #86d9ab;
+  color: #FFFFFF;
+}
+
+.popover-success .popover-title {
+  background-color: #86d9ab;
+  color: rgba(0, 0, 0, 0.56);
+}
+
+.popover-success.bottom .arrow:after {
+  border-bottom-color: #86d9ab;
+}
+
+.popover-success.left>.arrow::after {
+  border-left-color: #86d9ab;
+}
+
+.popover-success.top>.arrow::after {
+  border-top-color: #86d9ab;
+}
+
+.popover-success.right>.arrow::after {
+  border-right-color: #86d9ab;
+}
+
+.popover-warning {
+  background-color: #fcd27b;
+  color: #FFFFFF;
+}
+
+.popover-warning .popover-title {
+  background-color: #fcd27b;
+  color: rgba(0, 0, 0, 0.56);
+}
+
+.popover-warning.bottom .arrow:after {
+  border-bottom-color: #fcd27b;
+}
+
+.popover-warning.left>.arrow::after {
+  border-left-color: #fcd27b;
+}
+
+.popover-warning.top>.arrow::after {
+  border-top-color: #fcd27b;
+}
+
+.popover-warning.right>.arrow::after {
+  border-right-color: #fcd27b;
+}
+
+.popover-danger {
+  background-color: #f7765f;
+  color: #FFFFFF;
+}
+
+.popover-danger .popover-title {
+  background-color: #f7765f;
+  color: rgba(0, 0, 0, 0.56);
+}
+
+.popover-danger.bottom .arrow:after {
+  border-bottom-color: #f7765f;
+}
+
+.popover-danger.left>.arrow::after {
+  border-left-color: #f7765f;
+}
+
+.popover-danger.top>.arrow::after {
+  border-top-color: #f7765f;
+}
+
+.popover-danger.right>.arrow::after {
+  border-right-color: #f7765f;
+}
+
+.popover-primary.bs-tether-element-attached-bottom::after,
+.popover-primary.bs-tether-element-attached-bottom::before,
+.popover-primary.popover-top::after,
+.popover-primary.popover-top::before {
+  border-top-color: #6dd3d6 !important;
+}
+
+.popover.popover-info.bs-tether-element-attached-top::after,
+.popover.popover-info.popover-bottom::after,
+.popover.popover-info.bs-tether-element-attached-top::before,
+.popover.popover-info.popover-bottom::before {
+  border-bottom-color: #6ec7e0 !important;
+}
+
+.popover-success.bs-tether-element-attached-left::after,
+.popover-success.bs-tether-element-attached-left::before,
+.popover-success.popover-right::after,
+.popover-success.popover-right::before {
+  border-right-color: #86d9ab !important;
+}
+
+.popover.popover-warning.bs-tether-element-attached-right::after,
+.popover.popover-warning.bs-tether-element-attached-right::before,
+.popover.popover-warning.popover-left::after,
+.popover.popover-warning.popover-left::before {
+  border-left-color: #fcd27b !important;
+}
+
+.popover.popover-danger.bs-tether-element-attached-right::after,
+.popover.popover-danger.bs-tether-element-attached-right::before,
+.popover.popover-danger.popover-left::after,
+.popover.popover-danger.popover-left::before {
+  border-left-color: #f7765f !important;
+}
+
+.popover.bs-tether-element-attached-top::after,
+.popover.popover-bottom::after,
+.popover.bs-tether-element-attached-top::before,
+.popover.popover-bottom::before {
+  border-bottom-color: #fff !important;
+}
+
+.modal-header {
+  border-bottom: 1px solid #DDDDDD;
+  padding: 20px;
+  text-align: center;
+  display: block !important;
+}
+
+.modal-header.no-border-header {
+  border-bottom: 0 none !important;
+}
+
+.modal-header.no-border-header .modal-title {
+  margin-top: 20px;
+}
+
+.modal-header button.close:focus {
+  outline: none;
+}
+
+.modal-dialog.modal-sm .modal-header button.close,
+.modal-dialog.modal-register .modal-header button.close {
+  margin-top: 0;
+}
+
+.modal-content {
+  border: 0 none;
+  border-radius: 10px;
+  box-shadow: 0 0 15px rgba(0, 0, 0, 0.15), 0 0 1px 1px rgba(0, 0, 0, 0.1);
+}
+
+.modal-content .modal-header h6 {
+  margin-top: 10px;
+}
+
+.modal-dialog {
+  padding-top: 60px;
+}
+
+.modal-body {
+  padding: 20px 50px;
+  color: #000;
+}
+
+.modal-footer {
+  border-top: 1px solid #DDDDDD;
+  padding: 0px;
+}
+
+.modal-footer.no-border-footer {
+  border-top: 0 none;
+}
+
+.modal-footer .left-side,
+.modal-footer .right-side {
+  display: inline-block;
+  text-align: center;
+  width: 49%;
+}
+
+.modal-footer .btn-link {
+  padding: 20px;
+  width: 100%;
+}
+
+.modal-footer .divider {
+  background-color: #DDDDDD;
+  display: inline-block;
+  float: inherit;
+  height: 63px;
+  margin: 0px -3px;
+  width: 1px;
+}
+
+.modal-register .modal-footer {
+  text-align: center;
+  margin-bottom: 25px;
+  padding: 20px 0 15px;
+}
+
+.modal-register .modal-footer span {
+  width: 100%;
+}
+
+.modal-header:after {
+  display: table;
+  content: " ";
+}
+
+.modal-header:before {
+  display: table;
+  content: " ";
+}
+
+.section-nucleo-icons {
+  padding: 100px 0;
+}
+
+.section-nucleo-icons .icons-container {
+  position: relative;
+  max-width: 450px;
+  height: 300px;
+  max-height: 300px;
+  margin: 0 auto;
+}
+
+.section-nucleo-icons .icons-container i {
+  font-size: 34px;
+  position: absolute;
+  top: 0;
+  left: 0;
+}
+
+.section-nucleo-icons .icons-container i:nth-child(1) {
+  top: 5%;
+  left: 7%;
+}
+
+.section-nucleo-icons .icons-container i:nth-child(2) {
+  top: 28%;
+  left: 24%;
+}
+
+.section-nucleo-icons .icons-container i:nth-child(3) {
+  top: 40%;
+}
+
+.section-nucleo-icons .icons-container i:nth-child(4) {
+  top: 18%;
+  left: 62%;
+}
+
+.section-nucleo-icons .icons-container i:nth-child(5) {
+  top: 74%;
+  left: 3%;
+}
+
+.section-nucleo-icons .icons-container i:nth-child(6) {
+  top: 36%;
+  left: 44%;
+  font-size: 65px;
+  color: #f5593d;
+  padding: 1px;
+}
+
+.section-nucleo-icons .icons-container i:nth-child(7) {
+  top: 59%;
+  left: 26%;
+}
+
+.section-nucleo-icons .icons-container i:nth-child(8) {
+  top: 60%;
+  left: 69%;
+}
+
+.section-nucleo-icons .icons-container i:nth-child(9) {
+  top: 72%;
+  left: 47%;
+}
+
+.section-nucleo-icons .icons-container i:nth-child(10) {
+  top: 88%;
+  left: 27%;
+}
+
+.section-nucleo-icons .icons-container i:nth-child(11) {
+  top: 31%;
+  left: 80%;
+}
+
+.section-nucleo-icons .icons-container i:nth-child(12) {
+  top: 88%;
+  left: 68%;
+}
+
+.section-nucleo-icons .icons-container i:nth-child(13) {
+  top: 5%;
+  left: 81%;
+}
+
+.section-nucleo-icons .icons-container i:nth-child(14) {
+  top: 58%;
+  left: 90%;
+}
+
+.section-nucleo-icons .icons-container i:nth-child(15) {
+  top: 6%;
+  left: 40%;
+}
+
+.section-dark .icons-container {
+  color: #FFFFFF;
+}
+
+.info .icon {
+  margin-top: 0;
+  font-size: 3.4em;
+}
+
+.icon-primary {
+  color: #51cbce;
+}
+
+.icon-info {
+  color: #51bcda;
+}
+
+.icon-success {
+  color: #6bd098;
+}
+
+.icon-warning {
+  color: #fbc658;
+}
+
+.icon-danger {
+  color: #f5593d;
+}
+
+.icon-neutral {
+  color: #FFFFFF;
+}
+
+.carousel-control {
+  background-color: #f5593d;
+  border-radius: 50%;
+  opacity: 1;
+  text-shadow: none;
+}
+
+.carousel-control:hover,
+.carousel-control:focus {
+  opacity: 1;
+  background-color: #f33816;
+}
+
+.carousel-control.left {
+  height: 30px;
+  top: 50%;
+  width: 30px;
+  left: 25px;
+  opacity: 0;
+}
+
+.carousel-control.right {
+  height: 30px;
+  right: 25px;
+  top: 50%;
+  width: 30px;
+  opacity: 0;
+}
+
+.carousel-control .icon-prev,
+.carousel-control .icon-next,
+.carousel-control .fa,
+.carousel-control .fa {
+  display: inline-block;
+  z-index: 5;
+}
+
+.carousel-control .fa {
+  font-size: 26px;
+  margin: 2px;
+}
+
+.carousel-control.left,
+.carousel-control.right {
+  background-image: none;
+}
+
+.page-carousel {
+  border-radius: 12px !important;
+  border: none !important;
+  width: 100%;
+}
+
+.carousel-inner>.carousel-item>img,
+.carousel-inner>.carousel-item>a>img {
+  border-radius: 12px;
+  box-shadow: 0 2px 2px rgba(204, 197, 185, 0.5);
+}
+
+.carousel-inner .carousel-item img {
+  width: 100%;
+}
+
+.carousel-indicators>li {
+  background-color: rgba(204, 204, 204, 0.49);
+  border: 0 none;
+}
+
+.carousel-indicators .active {
+  background-color: #f5593d;
+}
+
+.page-carousel:hover .carousel-control.right,
+.page-carousel:hover .carousel-control.left {
+  opacity: 1;
+  z-index: 1;
+}
+
+.card .carousel .carousel-indicators {
+  bottom: 0;
+}
+
+.card .carousel a {
+  position: absolute;
+  color: #FFFFFF !important;
+}
+
+.card .carousel a:hover {
+  color: #FFFFFF !important;
+}
+
+.card .carousel a .fa-angle-left:before {
+  padding-right: 3px;
+}
+
+.card .carousel a .fa-angle-right:before {
+  padding-left: 3px;
+}
+
+.footer {
+  background-attachment: fixed;
+  position: relative;
+  line-height: 20px;
+}
+
+.footer .footer-nav ul {
+  padding-left: 0;
+  margin-bottom: 0;
+}
+
+.footer nav>ul {
+  list-style: none;
+  font-weight: normal;
+}
+
+.footer nav>ul>li {
+  display: inline-block;
+  padding: 10px 15px;
+  margin: 15px 3px;
+  line-height: 20px;
+  text-align: center;
+}
+
+.footer nav>ul a:not(.btn) {
+  color: #777777;
+  display: block;
+  margin-bottom: 3px;
+  line-height: 1.6;
+  opacity: .8;
+  font-size: 12px;
+  text-transform: uppercase;
+  font-weight: 600;
+}
+
+.footer nav>ul a:not(.btn):hover,
+.footer nav>ul a:not(.btn):focus {
+  color: #777777;
+  opacity: 1;
+}
+
+.footer .copyright {
+  color: #777777;
+  padding: 10px 0px;
+  font-size: 14px;
+  margin: 15px 3px;
+  line-height: 20px;
+  text-align: center;
+}
+
+.footer .heart {
+  color: #EB5E28;
+}
+
+.footer {
+  background-color: #FFFFFF;
+  line-height: 36px;
+}
+
+.footer.footer-black h4 {
+  color: #FFFFFF;
+}
+
+.footer .links {
+  display: inline-block;
+}
+
+.footer .links ul {
+  list-style: none;
+  margin: 0;
+  padding: 0;
+  font-weight: 600;
+}
+
+.footer .links ul>li {
+  display: inline-block;
+  padding-right: 20px;
+}
+
+.footer .links ul>li:last-child {
+  padding-right: 0px;
+}
+
+.footer .links ul a:not(.btn) {
+  color: #66615b;
+  display: block;
+  font-size: 0.9em;
+  margin-bottom: 3px;
+}
+
+.footer .links ul a:not(.btn):hover,
+.footer .links ul a:not(.btn):focus {
+  color: #403D39;
+}
+
+.footer .links ul.uppercase-links {
+  text-transform: uppercase;
+}
+
+.footer .links ul.stacked-links {
+  margin-top: 10px;
+}
+
+.footer .links ul.stacked-links>li {
+  display: block;
+  line-height: 26px;
+}
+
+.footer .links ul.stacked-links h4 {
+  margin-top: 0px;
+}
+
+.footer .social-area {
+  padding: 15px 0;
+}
+
+.footer .social-area .btn {
+  margin-bottom: 3px;
+  padding: 8px;
+}
+
+.footer .social-area .btn i {
+  margin-right: 0 !important;
+  color: #fff;
+}
+
+.footer hr {
+  border-color: #DDDDDD;
+  border-width: 1px 0 0;
+  margin-top: 5px;
+  margin-bottom: 5px;
+}
+
+.footer .copyright {
+  color: #A49E9E;
+  font-size: 0.9em;
+}
+
+.footer .copyright ul>li {
+  padding-right: 0px;
+}
+
+.footer .title {
+  color: #403D39;
+}
+
+.card {
+  border-radius: 12px;
+  box-shadow: 0 6px 10px -4px rgba(0, 0, 0, 0.15);
+  background-color: #FFFFFF;
+  color: #333333;
+  margin-bottom: 20px;
+  position: relative;
+  z-index: 1;
+  border: 0 none;
+  -webkit-transition: transform 300ms cubic-bezier(0.34, 2, 0.6, 1), box-shadow 200ms ease;
+  -moz-transition: transform 300ms cubic-bezier(0.34, 2, 0.6, 1), box-shadow 200ms ease;
+  -o-transition: transform 300ms cubic-bezier(0.34, 2, 0.6, 1), box-shadow 200ms ease;
+  -ms-transition: transform 300ms cubic-bezier(0.34, 2, 0.6, 1), box-shadow 200ms ease;
+  transition: transform 300ms cubic-bezier(0.34, 2, 0.6, 1), box-shadow 200ms ease;
+}
+
+.card:not(.card-plain):hover {
+  box-shadow: 0px 12px 19px -7px rgba(0, 0, 0, 0.3);
+  transform: translateY(-10px);
+  -webkit-transform: translateY(-10px);
+  -ms-transform: translateY(-10px);
+  -moz-transform: translateY(-10px);
+}
+
+.card.no-transition:hover,
+.card.page-carousel:hover,
+.card.card-refine:hover,
+.card.card-register:hover {
+  box-shadow: 0 6px 10px -4px rgba(0, 0, 0, 0.15);
+  transform: none;
+  -webkit-transform: none;
+  -ms-transform: none;
+  -moz-transform: none;
+}
+
+.card a:not(.btn) {
+  color: #444444;
+}
+
+.card a:not(.btn):hover,
+.card a:not(.btn):focus {
+  color: #333333;
+}
+
+.card .card-description {
+  color: #9A9A9A;
+  margin-bottom: 5px;
+  margin-top: 15px;
+}
+
+.card img {
+  max-width: 100%;
+  height: auto;
+  border-radius: 12px 12px 0 0;
+}
+
+.card[data-radius="none"] {
+  border-radius: 0px;
+}
+
+.card[data-radius="none"] .header {
+  border-radius: 0px 0px 0 0;
+}
+
+.card[data-radius="none"] .header img {
+  border-radius: 0px 0px 0 0;
+}
+
+.card.card-plain {
+  background-color: transparent;
+  box-shadow: none;
+  border-radius: 0;
+}
+
+.card.card-plain .card-body {
+  padding-left: 5px;
+  padding-right: 5px;
+}
+
+.card.card-plain img {
+  border-radius: 12px;
+}
+
+.card .card-link {
+  color: #FFFFFF;
+}
+
+.card .card-background-image ul li {
+  color: #FFF;
+  border-color: rgba(255, 255, 255, 0.3);
+}
+
+.card.card-blog,
+.card.card-testimonial .card-description+.card-title {
+  margin-top: 30px;
+}
+
+.card.card-blog .card-image .img,
+.card.card-testimonial .card-description+.card-title .card-image .img {
+  border-radius: 12px;
+}
+
+.card.card-blog .card-image .card-title,
+.card.card-testimonial .card-description+.card-title .card-image .card-title {
+  text-align: center;
+}
+
+.card.card:not(.card-plain) .card-image .img {
+  border-bottom-left-radius: 0px;
+  border-bottom-right-radius: 0px;
+}
+
+.card.card-blog {
+  margin-top: 5px;
+}
+
+.card.card-blog .btn {
+  margin: 0 auto;
+}
+
+.card .author {
+  display: inline-block;
+}
+
+.card .author .avatar {
+  width: 30px;
+  height: 30px;
+  overflow: hidden;
+  border-radius: 50%;
+  margin-right: 5px;
+}
+
+.card .author .avatar-big {
+  width: 100px;
+  height: 100px;
+  border-radius: 50% !important;
+  position: relative;
+  margin-bottom: 15px;
+}
+
+.card .author .avatar-big.border-white {
+  border: 4px solid #FFFFFF;
+}
+
+.card .author .avatar-big.border-gray {
+  border: 4px solid #ccc;
+}
+
+.card .clearfix+.author {
+  margin-top: 15px;
+}
+
+.card .stats {
+  display: inline-block;
+  float: right;
+  color: #9A9A9A;
+  font-size: 12px;
+  margin-top: 6px;
+}
+
+.card .stats i {
+  font-size: 16px;
+  position: relative;
+  text-align: center;
+  top: 1px;
+  margin-left: 5px;
+  margin-top: -1px;
+  opacity: .6;
+}
+
+.card .card-category {
+  color: #9A9A9A;
+}
+
+.card .category-social .fa {
+  font-size: 24px;
+  position: relative;
+  margin-top: -4px;
+  top: 2px;
+  margin-right: 5px;
+}
+
+.card .card-title-uppercase {
+  text-transform: uppercase;
+}
+
+.card .header {
+  position: relative;
+  border-radius: 3px 3px 0 0;
+  z-index: 3;
+}
+
+.card .header.header-with-icon {
+  height: 150px;
+}
+
+.card .header img {
+  width: 100%;
+}
+
+.card .header .card-category {
+  padding: 15px;
+}
+
+.card .card-body .card-footer {
+  padding: 0;
+}
+
+.card .card-body .card-description+.card-footer {
+  padding-top: 10px;
+}
+
+.card .more {
+  float: right;
+  z-index: 4;
+  display: block;
+  padding-top: 10px;
+  padding-right: 10px;
+  position: relative;
+}
+
+.card .filter,
+.card .header .actions {
+  position: absolute;
+  z-index: 2;
+  background-color: rgba(0, 0, 0, 0.76);
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  text-align: center;
+  opacity: 0;
+}
+
+.card .header .actions {
+  background-color: transparent;
+  z-index: 3;
+}
+
+.card .header .actions .btn {
+  position: relative;
+  top: 50%;
+  -webkit-transform: translateY(-50%);
+  -ms-transform: translateY(-50%);
+  transform: translateY(-50%);
+}
+
+.card:hover .filter {
+  opacity: .7;
+}
+
+.card:hover .header .social-line,
+.card:hover .header .actions {
+  opacity: 1;
+}
+
+.card .card-category i,
+.card .label i {
+  font-size: 15px;
+}
+
+.card>.card-title {
+  margin: 0;
+  padding: 30px 0 0;
+}
+
+.card .card-body {
+  padding: 20px;
+}
+
+.card .card-body .card-title {
+  margin: 5px 0 0 0;
+}
+
+.card .card-body .card-category~.card-title {
+  margin-top: 5px;
+}
+
+.card .card-text {
+  font-size: 15px;
+  color: #66615b;
+  padding-bottom: 15px;
+}
+
+.card h6 {
+  font-size: 12px;
+  margin: 0;
+}
+
+.card .card-footer {
+  padding: 15px;
+  background: transparent;
+  border-top: 0 none;
+}
+
+.card .card-footer .social-line .btn:first-child {
+  border-radius: 0 0 0 6px;
+}
+
+.card .card-footer .social-line .btn:last-child {
+  border-radius: 0 0 6px 0;
+}
+
+.card.card-separator:after {
+  height: 100%;
+  right: -15px;
+  top: 0;
+  width: 1px;
+  background-color: #DDDDDD;
+  content: "";
+  position: absolute;
+}
+
+.card .card-icon {
+  display: block;
+  margin: 0 auto;
+  position: relative;
+  text-align: center;
+  padding: 30px 0 10px;
+}
+
+.card .card-icon i {
+  font-size: 40px;
+  width: 105px;
+  border: 2px solid #ccc;
+  border-radius: 50%;
+  height: 105px;
+  line-height: 105px;
+}
+
+.col-lg-4 .card .card-icon i {
+  font-size: 80px;
+  padding: 22px;
+}
+
+.card.card-with-border .card-body {
+  padding: 15px 15px 25px 15px;
+}
+
+.card.card-with-border .card-footer {
+  padding-bottom: 25px;
+}
+
+.card.card-with-border:after {
+  position: absolute;
+  display: block;
+  width: calc(100% - 10px);
+  height: calc(100% - 10px);
+  content: "";
+  top: 5px;
+  left: 5px;
+  border: 1px solid rgba(0, 0, 0, 0.15);
+  z-index: 1;
+  border-radius: 5px;
+}
+
+.card.card-just-text .card-body {
+  padding: 50px 65px;
+  text-align: center;
+}
+
+.card.card-just-text #dLabel {
+  float: right;
+}
+
+.card.card-just-text #dLabel i {
+  font-size: 20px;
+}
+
+.card.card-just-text .dropdown-menu {
+  margin-top: 55px;
+}
+
+.card[data-background="image"] {
+  background-position: center center;
+  background-size: cover;
+  text-align: center;
+}
+
+.card[data-background="image"] .card-body {
+  position: relative;
+  z-index: 2;
+  min-height: 280px;
+  padding-top: 40px;
+  padding-bottom: 40px;
+  max-width: 440px;
+  margin: 0 auto;
+  text-align: center;
+}
+
+.card[data-background="image"] .card-title {
+  color: #FFF;
+  margin-top: 10px;
+}
+
+.card[data-background="image"]:after {
+  position: absolute;
+  z-index: 1;
+  width: 100%;
+  height: 100%;
+  display: block;
+  left: 0;
+  top: 0;
+  content: "";
+  background-color: rgba(0, 0, 0, 0.56);
+  border-radius: 12px;
+}
+
+.card[data-background="image"] .card-category {
+  color: #FFFFFF;
+}
+
+.card[data-background="image"] .image,
+.card[data-background="color"] .image,
+.card[data-color] .image {
+  border-radius: 6px;
+}
+
+.card[data-background="image"] .filter,
+.card[data-background="color"] .filter,
+.card[data-color] .filter {
+  border-radius: 6px;
+}
+
+.card[data-background="image"] .card-description,
+.card[data-background="color"] .card-description,
+.card[data-color] .card-description {
+  color: rgba(255, 255, 255, 0.8);
+}
+
+.card[data-background="image"] .card-title,
+.card[data-background="image"] .card-category,
+.card[data-background="image"] .card-text,
+.card[data-background="image"] .card-body,
+.card[data-background="image"] .card-footer,
+.card[data-background="image"] .stats,
+.card[data-background="image"] small,
+.card[data-background="image"] [class*="text-"],
+.card[data-background="image"] ul li b,
+.card[data-background="image"] a:not(.btn),
+.card[data-background="color"] .card-title,
+.card[data-background="color"] .card-category,
+.card[data-background="color"] .card-text,
+.card[data-background="color"] .card-body,
+.card[data-background="color"] .card-footer,
+.card[data-background="color"] .stats,
+.card[data-background="color"] small,
+.card[data-background="color"] [class*="text-"],
+.card[data-background="color"] ul li b,
+.card[data-background="color"] a:not(.btn),
+.card[data-color] .card-title,
+.card[data-color] .card-category,
+.card[data-color] .card-text,
+.card[data-color] .card-body,
+.card[data-color] .card-footer,
+.card[data-color] .stats,
+.card[data-color] small,
+.card[data-color] [class*="text-"],
+.card[data-color] ul li b,
+.card[data-color] a:not(.btn) {
+  color: #FFFFFF !important;
+}
+
+.card[data-background="image"] a:not(.btn):hover,
+.card[data-background="image"] a:not(.btn):focus,
+.card[data-background="color"] a:not(.btn):hover,
+.card[data-background="color"] a:not(.btn):focus,
+.card[data-color] a:not(.btn):hover,
+.card[data-color] a:not(.btn):focus {
+  color: #FFFFFF;
+}
+
+.card[data-background="image"] .card-icon i,
+.card[data-background="color"] .card-icon i,
+.card[data-color] .card-icon i {
+  color: #FFFFFF;
+  border: 2px solid rgba(255, 255, 255, 0.3);
+}
+
+.card[data-background="image"].card-with-border:after,
+.card[data-background="color"].card-with-border:after,
+.card[data-color].card-with-border:after {
+  border: 1px solid rgba(255, 255, 255, 0.45);
+}
+
+.card[data-background="image"] .filter {
+  opacity: 0.55;
+  filter: alpha(opacity=55);
+}
+
+.card[data-background="image"]:hover .filter {
+  opacity: 0.75;
+  filter: alpha(opacity=75);
+}
+
+.card[data-color="blue"] {
+  background: #6ec7e0;
+}
+
+.card[data-color="green"] {
+  background: #86d9ab;
+}
+
+.card[data-color="yellow"] {
+  background: #fcd27b;
+}
+
+.card[data-color="brown"] {
+  background: #e4c4a1;
+}
+
+.card[data-color="purple"] {
+  background: #cc90cc;
+}
+
+.card[data-color="orange"] {
+  background: #f7765f;
+}
+
+.btn-center {
+  text-align: center;
+}
+
+.card-big-shadow {
+  max-width: 320px;
+  position: relative;
+}
+
+.card-big-shadow:before {
+  background-image: url("http://static.tumblr.com/i21wc39/coTmrkw40/shadow.png");
+  background-position: center bottom;
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  bottom: -12%;
+  content: "";
+  display: block;
+  left: -12%;
+  position: absolute;
+  right: 0;
+  top: 0;
+  z-index: 0;
+}
+
+.card-image.card-big-shadow {
+  max-width: 100%;
+}
+
+.card-image .card {
+  background-size: cover;
+  min-height: 430px;
+  width: 100%;
+}
+
+.card-image .img-raised {
+  margin-top: -20px;
+}
+
+.page-header .card-pricing.card-plain .card-category,
+.page-header .card-pricing.card-plain .card-title {
+  color: #FFFFFF;
+}
+
+.card-plain .card-avatar {
+  margin-top: 0;
+}
+
+.card-refine .panel-title {
+  font-size: 1em;
+}
+
+.card-plain {
+  background-color: transparent;
+  box-shadow: none;
+  border-radius: 0;
+}
+
+.card-plain .card-body {
+  padding-left: 5px;
+  padding-right: 5px;
+}
+
+.card-plain img {
+  border-radius: 12px;
+}
+
+.card-register {
+  background-color: #FF8F5E;
+  border-radius: 8px;
+  color: #fff;
+  max-width: 350px;
+  margin: 20px 0 70px;
+  min-height: 400px;
+  padding: 30px;
+}
+
+.card-register label {
+  margin-top: 15px;
+}
+
+.card-register .card-title {
+  color: #B33C12;
+  text-align: center;
+}
+
+.card-register .btn {
+  margin-top: 30px;
+}
+
+.card-register .forgot {
+  text-align: center;
+}
+
+.card-register .input-group-text {
+  border: 1px solid #FFFFFF;
+}
+
+.card-profile {
+  margin-top: 30px;
+  text-align: center;
+}
+
+.card-profile .card-cover {
+  height: 130px;
+  background-position: center center;
+  background-size: cover;
+  border-radius: 12px 12px 0 0;
+}
+
+.card-profile .card-body .card-title {
+  margin-top: 5px !important;
+}
+
+.card-profile .card-body .card-category {
+  margin-bottom: 5px;
+  margin-top: 5px;
+}
+
+.card-profile .card-avatar {
+  max-width: 120px;
+  max-height: 120px;
+  margin: -60px auto 0;
+  border-radius: 50%;
+  overflow: hidden;
+}
+
+.card-profile .card-avatar.border-white {
+  border: 4px solid #FFFFFF;
+}
+
+.card-profile .card-avatar.border-gray {
+  border: 4px solid #ccc;
+}
+
+.section .card-profile {
+  margin-top: 100px;
+}
+
+.landing-alert {
+  margin-bottom: 0;
+}
+
+.page-header {
+  background-color: #B2AFAB;
+  background-position: center center;
+  background-size: cover;
+  min-height: 100vh;
+  max-height: 999px;
+  overflow: hidden;
+  position: relative;
+  width: 100%;
+  z-index: 1;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.page-header .filter::after {
+  background-color: rgba(0, 0, 0, 0.5);
+  content: "";
+  display: block;
+  height: 100%;
+  left: 0;
+  top: 0;
+  position: absolute;
+  width: 100%;
+  z-index: 1;
+}
+
+.page-header.page-header-small {
+  min-height: 65vh !important;
+  max-height: 700px;
+}
+
+.page-header.page-header-xs {
+  min-height: 40vh !important;
+}
+
+.page-header.section-dark .content-center,
+.page-header.section-dark .category-absolute {
+  z-index: 1;
+}
+
+.page-header .motto {
+  text-align: left;
+  z-index: 3;
+  color: #fff;
+  position: relative;
+}
+
+.landing-section {
+  padding: 100px 0;
+  z-index: 1;
+}
+
+.section-buttons {
+  z-index: 1;
+}
+
+.landing-section .btn-simple {
+  padding: 0;
+}
+
+.landing-section .column {
+  padding: 0 75px 0 25px;
+}
+
+.team-player .img-circle,
+.team-player .img-thumbnail {
+  display: block;
+  margin-top: 50px;
+  margin-left: auto;
+  margin-right: auto;
+  width: 120px;
+}
+
+.contact-form {
+  margin-top: 30px;
+}
+
+.contact-form label {
+  margin-top: 15px;
+}
+
+.contact-form .btn {
+  margin-top: 30px;
+}
+
+.navbar-relative {
+  position: relative;
+  z-index: 2;
+}
+
+#register-navbar a {
+  color: #FFF;
+}
+
+.register-background .container {
+  margin-top: 11%;
+  position: relative;
+  z-index: 3;
+}
+
+.register-footer {
+  bottom: 20px;
+  position: absolute;
+  z-index: 1;
+  width: 100%;
+  background: transparent;
+  color: #FFFFFF;
+}
+
+.register-footer .fa-heart {
+  color: #EB5E28;
+}
+
+.register-card label {
+  margin-top: 15px;
+}
+
+.register-card .title {
+  color: #B33C12;
+  text-align: center;
+}
+
+.register-card .btn {
+  margin-top: 30px;
+}
+
+.register-card .forgot {
+  text-align: center;
+}
+
+.profile-content {
+  position: relative;
+}
+
+.owner {
+  text-align: center;
+}
+
+.owner .avatar {
+  padding: 15px;
+  max-width: 180px;
+  margin: -85px auto 0;
+  display: inline-block;
+}
+
+.owner .name h4 {
+  margin-top: 10px;
+}
+
+.profile-tabs {
+  margin: 50px 0;
+  min-height: 300px;
+}
+
+#following h3 {
+  margin: 20px 0 40px 0;
+}
+
+#follows .follows .unfollow .checkbox {
+  margin-top: -15px;
+}
+
+#follows .follows h6 {
+  margin-top: 15px;
+}
+
+.follows hr {
+  margin-top: 10px;
+}
+
+.title-brand {
+  max-width: 730px;
+  margin: 0 auto;
+  position: relative;
+  text-align: center;
+  color: #FFFFFF;
+  display: block;
+}
+
+.title-brand .type {
+  position: absolute;
+  font-size: 20px;
+  background: #132026;
+  padding: 6px 10px;
+  border-radius: 4px;
+  top: 0;
+  font-weight: 600;
+  margin-top: 10px;
+  right: -15px;
+}
+
+.presentation-title {
+  font-size: 8em;
+  font-weight: 700;
+  margin: 0;
+  color: #FFFFFF;
+  background: #fbf8ec;
+  background: -moz-linear-gradient(top, #FFFFFF 35%, #4e6773 100%);
+  background: -webkit-linear-gradient(top, #FFFFFF 35%, #4e6773 100%);
+  background: -ms-linear-gradient(top, #FFFFFF 35%, #4e6773 100%);
+  background: linear-gradient(to bottom, #FFFFFF 35%, #4e6773 100%);
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+}
+
+.presentation-subtitle {
+  font-size: 1.7em;
+  color: #FFFFFF;
+}
+
+.category-absolute {
+  position: absolute;
+  text-align: center;
+  top: 100vh;
+  margin-top: -60px;
+  padding: 0 15px;
+  width: 100%;
+  color: rgba(255, 255, 255, 0.5);
+}
+
+.category-absolute .creative-tim-logo {
+  max-width: 140px;
+  top: -2px;
+  left: 3px;
+  position: relative;
+}
+
+.fog-low {
+  position: absolute;
+  left: 0;
+  bottom: 0;
+  margin-left: -35%;
+  margin-bottom: -50px;
+  width: 110%;
+  opacity: .85;
+}
+
+.fog-low img {
+  width: 100%;
+}
+
+.fog-low.right {
+  margin-left: 30%;
+  opacity: 1;
+}
+
+.page-header .content-center {
+  margin-top: 85px;
+}
+
+.moving-clouds {
+  position: absolute;
+  z-index: 1;
+  bottom: 0;
+  left: 0;
+  width: 250.625em;
+  height: 43.75em;
+  -webkit-animation: cloudLoop 80s linear infinite;
+  animation: cloudLoop 80s linear infinite;
+}
+
+@keyframes cloudLoop {
+  0% {
+    -webkit-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  100% {
+    -webkit-transform: translate3d(-50%, 0, 0);
+    transform: translate3d(-50%, 0, 0);
+  }
+}
+
+.following img {
+  max-width: 70px;
+}
+
+.profile-content .tab-content .tab-pane {
+  min-height: 200px;
+}
+
+.profile-content .tab-content #tweets,
+.profile-content .tab-content #connections,
+.profile-content .tab-content #media {
+  height: 100%;
+}
+
+.section {
+  padding: 70px 0;
+  position: relative;
+  background-color: #FFFFFF;
+}
+
+.section-with-space {
+  padding: 60px 0;
+}
+
+.section-gray {
+  background-color: #EEEEEE;
+}
+
+.section-nude {
+  background-color: #FFFCF5;
+}
+
+.section-gold {
+  background-color: #caac90;
+  color: #FFFFFF;
+}
+
+.section-brown {
+  background-color: #A59E94;
+  color: #FFFFFF;
+}
+
+.section-light-blue {
+  background-color: #51cbce;
+  color: #FFFFFF;
+}
+
+.section-dark-blue {
+  background-color: #506367;
+  color: #FFFFFF;
+}
+
+.section-dark {
+  background-color: #0b1011;
+}
+
+.section-image,
+.section-gold,
+.section-dark {
+  position: relative;
+}
+
+.section-image .title,
+.section-image .info-title,
+.section-image .card-plain .card-title,
+.section-gold .title,
+.section-gold .info-title,
+.section-gold .card-plain .card-title,
+.section-dark .title,
+.section-dark .info-title,
+.section-dark .card-plain .card-title {
+  color: #FFFFFF !important;
+}
+
+.section-image .category,
+.section-image .description,
+.section-image .card-plain .card-description,
+.section-image .card-plain .card-category,
+.section-gold .category,
+.section-gold .description,
+.section-gold .card-plain .card-description,
+.section-gold .card-plain .card-category,
+.section-dark .category,
+.section-dark .description,
+.section-dark .card-plain .card-description,
+.section-dark .card-plain .card-category {
+  color: rgba(255, 255, 255, 0.7);
+}
+
+.section-image hr,
+.section-gold hr,
+.section-dark hr {
+  border-color: rgba(255, 255, 255, 0.19);
+}
+
+.page-header .title,
+.page-header .info-title,
+.carousel-caption .title,
+.carousel-caption .info-title {
+  color: #FFFFFF;
+}
+
+[class*="features-"],
+[class*="team-"],
+[class*="projects-"],
+[class*="pricing-"],
+[class*="testimonials-"],
+[class*="contactus-"] {
+  padding: 80px 0;
+}
+
+.section-image {
+  background-position: center center;
+  background-size: cover;
+}
+
+.section-image:before {
+  background-color: rgba(0, 0, 0, 0.5);
+  content: "";
+  display: block;
+  height: 100%;
+  left: 0;
+  top: 0;
+  position: absolute;
+  width: 100%;
+  z-index: 1;
+}
+
+.section-image .container {
+  position: relative;
+  z-index: 2;
+}
+
+.section-login {
+  min-height: 700px;
+}
+
+@media all and (-ms-high-contrast: none),
+(-ms-high-contrast: active) {
+  /* IE10+ CSS styles go here */
+  .page-header .content-center {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -75%);
+  }
+  .page-header .presentation-title {
+    background: none !important;
+  }
+}
+
+[class*="features-"],
+[class*="team-"],
+[class*="projects-"],
+[class*="pricing-"],
+[class*="testimonials-"],
+[class*="contactus-"] {
+  padding: 80px 0;
+}
+
+.section-image {
+  background-position: center center;
+  background-size: cover;
+}
+
+.section-image:before {
+  background-color: rgba(0, 0, 0, 0.5);
+  content: "";
+  display: block;
+  height: 100%;
+  left: 0;
+  top: 0;
+  position: absolute;
+  width: 100%;
+  z-index: 1;
+}
+
+.section-image .container {
+  position: relative;
+  z-index: 2;
+}
+
+/*          Changes for small display      */
+
+@media (max-width: 767px) {
+  #cd-vertical-nav {
+    display: none !important;
+  }
+  .coloured-cards .card-big-shadow {
+    margin: 0 auto;
+  }
+  .register-page .page-header {
+    max-height: 2000px;
+  }
+  .section-testimonials .our-clients {
+    margin-top: 0 !important;
+  }
+  .navbar-transparent {
+    background-color: rgba(0, 0, 0, 0.45);
+  }
+  .register .page-header {
+    max-height: fit-content;
+  }
+  .form-group.has-danger {
+    margin-bottom: 30px;
+  }
+  body {
+    position: relative;
+    font-size: 12px;
+  }
+  h6 {
+    font-size: 1em;
+  }
+  .navbar .container {
+    left: 0;
+    width: 100%;
+    -webkit-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -moz-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -o-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -ms-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    position: relative;
+  }
+  .navbar .navbar-nav .dropdown-menu {
+    height: 400px;
+    overflow-y: scroll;
+  }
+  .demo-header .motto {
+    padding-top: 30% !important;
+  }
+  .navbar-toggle .icon-bar {
+    display: block;
+    position: relative;
+    background: #fff;
+    width: 24px;
+    height: 2px;
+    border-radius: 1px;
+    margin: 0 auto;
+  }
+  .navbar-header .navbar-toggle {
+    margin-top: 12px;
+    width: 40px;
+    height: 40px;
+  }
+  .bar1,
+  .bar2,
+  .bar3 {
+    outline: 1px solid transparent;
+  }
+  .bar1 {
+    top: 0px;
+    -webkit-animation: topbar-back 500ms linear 0s;
+    -moz-animation: topbar-back 500ms linear 0s;
+    animation: topbar-back 500ms 0s;
+    -webkit-animation-fill-mode: forwards;
+    -moz-animation-fill-mode: forwards;
+    animation-fill-mode: forwards;
+  }
+  .bar2 {
+    opacity: 1;
+  }
+  .bar3 {
+    bottom: 0px;
+    -webkit-animation: bottombar-back 500ms linear 0s;
+    -moz-animation: bottombar-back 500ms linear 0s;
+    animation: bottombar-back 500ms 0s;
+    -webkit-animation-fill-mode: forwards;
+    -moz-animation-fill-mode: forwards;
+    animation-fill-mode: forwards;
+  }
+  .toggled .bar1 {
+    top: 6px;
+    -webkit-animation: topbar-x 500ms linear 0s;
+    -moz-animation: topbar-x 500ms linear 0s;
+    animation: topbar-x 500ms 0s;
+    -webkit-animation-fill-mode: forwards;
+    -moz-animation-fill-mode: forwards;
+    animation-fill-mode: forwards;
+  }
+  .toggled .bar2 {
+    opacity: 0;
+  }
+  .toggled .bar3 {
+    bottom: 6px;
+    -webkit-animation: bottombar-x 500ms linear 0s;
+    -moz-animation: bottombar-x 500ms linear 0s;
+    animation: bottombar-x 500ms 0s;
+    -webkit-animation-fill-mode: forwards;
+    -moz-animation-fill-mode: forwards;
+    animation-fill-mode: forwards;
+  }
+  @keyframes topbar-x {
+    0% {
+      top: 0px;
+      transform: rotate(0deg);
+    }
+    45% {
+      top: 6px;
+      transform: rotate(145deg);
+    }
+    75% {
+      transform: rotate(130deg);
+    }
+    100% {
+      transform: rotate(135deg);
+    }
+  }
+  @-webkit-keyframes topbar-x {
+    0% {
+      top: 0px;
+      -webkit-transform: rotate(0deg);
+    }
+    45% {
+      top: 6px;
+      -webkit-transform: rotate(145deg);
+    }
+    75% {
+      -webkit-transform: rotate(130deg);
+    }
+    100% {
+      -webkit-transform: rotate(135deg);
+    }
+  }
+  @-moz-keyframes topbar-x {
+    0% {
+      top: 0px;
+      -moz-transform: rotate(0deg);
+    }
+    45% {
+      top: 6px;
+      -moz-transform: rotate(145deg);
+    }
+    75% {
+      -moz-transform: rotate(130deg);
+    }
+    100% {
+      -moz-transform: rotate(135deg);
+    }
+  }
+  @keyframes topbar-back {
+    0% {
+      top: 6px;
+      transform: rotate(135deg);
+    }
+    45% {
+      transform: rotate(-10deg);
+    }
+    75% {
+      transform: rotate(5deg);
+    }
+    100% {
+      top: 0px;
+      transform: rotate(0);
+    }
+  }
+  @-webkit-keyframes topbar-back {
+    0% {
+      top: 6px;
+      -webkit-transform: rotate(135deg);
+    }
+    45% {
+      -webkit-transform: rotate(-10deg);
+    }
+    75% {
+      -webkit-transform: rotate(5deg);
+    }
+    100% {
+      top: 0px;
+      -webkit-transform: rotate(0);
+    }
+  }
+  @-moz-keyframes topbar-back {
+    0% {
+      top: 6px;
+      -moz-transform: rotate(135deg);
+    }
+    45% {
+      -moz-transform: rotate(-10deg);
+    }
+    75% {
+      -moz-transform: rotate(5deg);
+    }
+    100% {
+      top: 0px;
+      -moz-transform: rotate(0);
+    }
+  }
+  @keyframes bottombar-x {
+    0% {
+      bottom: 0px;
+      transform: rotate(0deg);
+    }
+    45% {
+      bottom: 6px;
+      transform: rotate(-145deg);
+    }
+    75% {
+      transform: rotate(-130deg);
+    }
+    100% {
+      transform: rotate(-135deg);
+    }
+  }
+  @-webkit-keyframes bottombar-x {
+    0% {
+      bottom: 0px;
+      -webkit-transform: rotate(0deg);
+    }
+    45% {
+      bottom: 6px;
+      -webkit-transform: rotate(-145deg);
+    }
+    75% {
+      -webkit-transform: rotate(-130deg);
+    }
+    100% {
+      -webkit-transform: rotate(-135deg);
+    }
+  }
+  @-moz-keyframes bottombar-x {
+    0% {
+      bottom: 0px;
+      -moz-transform: rotate(0deg);
+    }
+    45% {
+      bottom: 6px;
+      -moz-transform: rotate(-145deg);
+    }
+    75% {
+      -moz-transform: rotate(-130deg);
+    }
+    100% {
+      -moz-transform: rotate(-135deg);
+    }
+  }
+  @keyframes bottombar-back {
+    0% {
+      bottom: 6px;
+      transform: rotate(-135deg);
+    }
+    45% {
+      transform: rotate(10deg);
+    }
+    75% {
+      transform: rotate(-5deg);
+    }
+    100% {
+      bottom: 0px;
+      transform: rotate(0);
+    }
+  }
+  @-webkit-keyframes bottombar-back {
+    0% {
+      bottom: 6px;
+      -webkit-transform: rotate(-135deg);
+    }
+    45% {
+      -webkit-transform: rotate(10deg);
+    }
+    75% {
+      -webkit-transform: rotate(-5deg);
+    }
+    100% {
+      bottom: 0px;
+      -webkit-transform: rotate(0);
+    }
+  }
+  @-moz-keyframes bottombar-back {
+    0% {
+      bottom: 6px;
+      -moz-transform: rotate(-135deg);
+    }
+    45% {
+      -moz-transform: rotate(10deg);
+    }
+    75% {
+      -moz-transform: rotate(-5deg);
+    }
+    100% {
+      bottom: 0px;
+      -moz-transform: rotate(0);
+    }
+  }
+  @-webkit-keyframes fadeIn {
+    0% {
+      opacity: 0;
+    }
+    100% {
+      opacity: 1;
+    }
+  }
+  @-moz-keyframes fadeIn {
+    0% {
+      opacity: 0;
+    }
+    100% {
+      opacity: 1;
+    }
+  }
+  @keyframes fadeIn {
+    0% {
+      opacity: 0;
+    }
+    100% {
+      opacity: 1;
+    }
+  }
+  .navbar-nav {
+    margin: 1px -15px;
+  }
+  .navbar-nav .open .dropdown-menu>li>a {
+    padding: 15px 15px 5px 50px;
+  }
+  .navbar-nav .open .dropdown-menu>li:first-child>a {
+    padding: 5px 15px 5px 50px;
+  }
+  .navbar-nav .open .dropdown-menu>li:last-child>a {
+    padding: 15px 15px 25px 50px;
+  }
+  [class*="navbar-"] .navbar-nav>li>a,
+  [class*="navbar-"] .navbar-nav>li>a:hover,
+  [class*="navbar-"] .navbar-nav>li>a:focus,
+  [class*="navbar-"] .navbar-nav .active>a,
+  [class*="navbar-"] .navbar-nav .active>a:hover,
+  [class*="navbar-"] .navbar-nav .active>a:focus,
+  [class*="navbar-"] .navbar-nav .open .dropdown-menu>li>a,
+  [class*="navbar-"] .navbar-nav .open .dropdown-menu>li>a:hover,
+  [class*="navbar-"] .navbar-nav .open .dropdown-menu>li>a:focus,
+  [class*="navbar-"] .navbar-nav .navbar-nav .open .dropdown-menu>li>a:active {
+    color: white;
+  }
+  [class*="navbar-"] .navbar-nav>li>a:not(.btn),
+  [class*="navbar-"] .navbar-nav>li>a:hover,
+  [class*="navbar-"] .navbar-nav>li>a:focus,
+  [class*="navbar-"] .navbar-nav .open .dropdown-menu>li>a:not(.btn),
+  [class*="navbar-"] .navbar-nav .open .dropdown-menu>li>a:hover,
+  [class*="navbar-"] .navbar-nav .open .dropdown-menu>li>a:focus {
+    opacity: .7;
+    background: transparent;
+  }
+  [class*="navbar-"] .navbar-nav.navbar-nav .open .dropdown-menu>li>a:active {
+    opacity: 1;
+  }
+  [class*="navbar-"] .navbar-nav .dropdown>a:hover .caret {
+    border-bottom-color: #777;
+    border-top-color: #777;
+  }
+  [class*="navbar-"] .navbar-nav .dropdown>a:active .caret {
+    border-bottom-color: white;
+    border-top-color: white;
+  }
+  .footer .footer-nav,
+  .footer .credits {
+    margin: 0 auto;
+  }
+  #typography .typography-line .note {
+    margin-left: 7px !important;
+  }
+  .dropdown-menu {
+    display: none;
+  }
+  .navbar-fixed-top {
+    -webkit-backface-visibility: hidden;
+  }
+  .social-line .btn {
+    margin: 0 0 10px 0;
+  }
+  .subscribe-line .form-control {
+    margin: 0 0 10px 0;
+  }
+  .social-line.pull-right {
+    float: none;
+  }
+  .footer nav.pull-left {
+    float: none !important;
+  }
+  .footer:not(.footer-big) nav>ul li {
+    float: none;
+  }
+  .social-area.pull-right {
+    float: none !important;
+  }
+  .form-control+.form-control-feedback {
+    margin-top: 5px;
+  }
+  .form-control.form-control-danger.no-border {
+    margin-top: 15px;
+  }
+  .navbar-toggle:hover,
+  .navbar-toggle:focus {
+    background-color: transparent !important;
+  }
+  .btn.dropdown-toggle {
+    margin-bottom: 0;
+  }
+  .media-post .author {
+    width: 25%;
+    float: none !important;
+    display: block;
+    margin: 0 auto 10px;
+  }
+  .media-post .media-body {
+    width: 100%;
+  }
+  .modal-footer .btn-simple {
+    padding: 15px;
+  }
+  .table-responsive {
+    width: 100%;
+    margin-bottom: 15px;
+    overflow-x: scroll;
+    overflow-y: hidden;
+    border: 1px solid #dddddd;
+    -ms-overflow-style: -ms-autohiding-scrollbar;
+    -webkit-overflow-scrolling: touch;
+  }
+  .typography-line {
+    padding-left: 100px !important;
+  }
+  .projects-1 .project-pills .nav.nav-pills {
+    display: block !important;
+  }
+  .projects-1 .project-pills .nav.nav-pills .nav-item:first-child .nav-link {
+    border-radius: 12px 12px 0 0 !important;
+    margin-left: -1px;
+  }
+  .projects-1 .project-pills .nav.nav-pills .nav-item.active:first-child .nav-link {
+    border-radius: 12px 12px 0 0 !important;
+    margin-left: -1px;
+  }
+  .projects-1 .project-pills .nav.nav-pills .nav-item:last-child .nav-link {
+    border-radius: 0 0 12px 12px !important;
+    margin-left: -1px;
+  }
+  .testimonials-2 .testimonials-people img,
+  .section-testimonials .testimonials-people img {
+    display: none !important;
+  }
+  .presentation-page .components-container .card {
+    margin-bottom: 40px !important;
+  }
+  .btn-wd {
+    min-width: 280px;
+  }
+  .presentation-page .title-brand .type {
+    font-size: 16px;
+    transform: translateY(-28px);
+    -webkit-transform: translateY(-28px);
+    -moz-transform: translateY(-28px);
+    -o-transform: translateY(-28px);
+  }
+  .presentation-page .section-cards,
+  .presentation-page .section-components {
+    overflow: hidden;
+  }
+  .presentation-page .section-cards .first-card,
+  .presentation-page .section-components .first-card {
+    top: 750px !important;
+  }
+  .presentation-page .section-cards .first-card .grid__link,
+  .presentation-page .section-components .first-card .grid__link {
+    max-width: 200px !important;
+  }
+  .presentation-page .section-cards .fourth-card,
+  .presentation-page .section-components .fourth-card {
+    top: 940px !important;
+  }
+  .presentation-page .section-cards .fourth-card .grid__link,
+  .presentation-page .section-components .fourth-card .grid__link {
+    max-width: 200px !important;
+  }
+  .presentation-page .section-cards .fifth-card,
+  .presentation-page .section-components .fifth-card {
+    top: 950px !important;
+    left: 220px !important;
+  }
+  .presentation-page .section-cards .fifth-card .grid__link,
+  .presentation-page .section-components .fifth-card .grid__link {
+    max-width: 200px !important;
+  }
+  .presentation-page .section-cards .sixth-card,
+  .presentation-page .section-components .sixth-card {
+    top: 1335px !important;
+    left: 220px !important;
+  }
+  .presentation-page .section-cards .sixth-card .grid__link,
+  .presentation-page .section-components .sixth-card .grid__link {
+    max-width: 200px !important;
+  }
+  .presentation-page .section-cards .seventh-card,
+  .presentation-page .section-components .seventh-card {
+    top: 1155px !important;
+  }
+  .presentation-page .section-cards .seventh-card .grid__link,
+  .presentation-page .section-components .seventh-card .grid__link {
+    max-width: 200px !important;
+  }
+  .presentation-page .section-content .image-container .add-animation {
+    max-height: 250px !important;
+    max-width: 180px !important;
+  }
+  .presentation-page .section-components .image-container .components-macbook {
+    max-width: 580px !important;
+    max-height: 400px !important;
+  }
+  .presentation-page .section-components .image-container .social-img,
+  .presentation-page .section-components .image-container .share-btn-img {
+    display: none;
+  }
+  .presentation-page .section-components .title {
+    margin-top: -100px !important;
+  }
+  .presentation-page .section-examples {
+    padding-top: 0 !important;
+    margin-top: 10px !important;
+  }
+  .presentation-page .section-icons .icons-nucleo .nc-icon:not(.ninth-left-icon):not(.seventh-left-icon):not(.third-left-icon) {
+    display: none !important;
+  }
+  .bootstrap-datetimepicker-widget {
+    visibility: visible !important;
+  }
+  .presentation-page .fog-low {
+    margin-bottom: -35px;
+  }
+  .presentation-page .presentation-title {
+    font-size: 5em;
+  }
+  .presentation-page .presentation-subtitle {
+    margin-top: 40px;
+  }
+  .presentation-page .title-brand {
+    max-width: 450px;
+  }
+  .presentation-page .title-brand .type {
+    font-size: 16px;
+  }
+  .demo-icons ul li {
+    width: 20%;
+    float: left;
+  }
+  .info.info-separator:after {
+    display: none;
+  }
+  .pricing-5 .choose-plan {
+    text-align: center;
+  }
+  .pricing-5 .choose-plan .nav.nav-pills {
+    display: inline-flex;
+  }
+  .pricing-5 .description {
+    text-align: center;
+  }
+  .page-carousel .carousel-inner [class*='col-md'] {
+    margin-left: 0 !important;
+  }
+  .page-carousel .right.carousel-control {
+    margin-right: 0 !important;
+  }
+  .page-carousel .left.carousel-control {
+    margin-left: 0 !important;
+  }
+  .subscribe-line .form-control {
+    border: 1px solid #DDDDDD;
+    padding-left: 10px;
+  }
+  .subscribe-line .btn {
+    margin: 0 auto;
+  }
+}
+
+@media screen and (max-width: 991px) {
+  .navbar-collapse {
+    position: fixed;
+    display: block !important;
+    top: 0;
+    height: 100%;
+    width: 230px;
+    right: 0;
+    z-index: 1032;
+    visibility: visible;
+    background-color: #999;
+    overflow-y: visible;
+    border-top: none;
+    text-align: left;
+    border-left: 1px solid #CCC5B9;
+    padding-right: 0px;
+    padding-left: 40px;
+    padding-top: 15px;
+    -webkit-transform: translateX(230px);
+    -moz-transform: translateX(230px);
+    -o-transform: translateX(230px);
+    -ms-transform: translateX(230px);
+    transform: translateX(230px);
+    -webkit-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -moz-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -o-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -ms-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+  }
+  .navbar-collapse ul {
+    position: relative;
+    z-index: 3;
+    height: 95%;
+  }
+  .navbar-collapse .navbar-nav>.nav-item:last-child {
+    border-bottom: 0;
+  }
+  .navbar-collapse .navbar-nav>.nav-item>.nav-link {
+    margin: 0px 0px;
+    color: #9A9A9A !important;
+    text-transform: uppercase;
+    font-weight: 600;
+    font-size: 12px;
+    line-height: 1.5em;
+    padding: 15px 0;
+  }
+  .navbar-collapse .navbar-nav>.nav-item>.nav-link:hover,
+  .navbar-collapse .navbar-nav>.nav-item>.nav-link:active {
+    color: #403D39 !important;
+  }
+  .navbar-collapse::after {
+    top: 0;
+    left: 0;
+    height: 100%;
+    width: 100%;
+    position: absolute;
+    background-color: #FFFCF5;
+    background-image: linear-gradient(to bottom, transparent 0%, rgba(112, 112, 112, 0) 60%, rgba(186, 186, 186, 0.15) 100%);
+    display: block;
+    content: "";
+    z-index: 1;
+  }
+  .navbar-collapse.has-image::after {
+    top: 0;
+    left: 0;
+    height: 100%;
+    width: 100%;
+    position: absolute;
+    background-color: rgba(17, 17, 17, 0.8);
+    display: block;
+    content: "";
+    z-index: 1;
+  }
+  .nav-open .navbar-collapse {
+    -webkit-transform: translateX(0px);
+    -moz-transform: translateX(0px);
+    -o-transform: translateX(0px);
+    -ms-transform: translateX(0px);
+    transform: translateX(0px);
+  }
+  .nav-open .wrapper {
+    left: 0;
+    -webkit-transform: translateX(-230px);
+    -moz-transform: translateX(-230px);
+    -o-transform: translateX(-230px);
+    -ms-transform: translateX(-230px);
+    transform: translateX(-230px);
+  }
+  .nav-open .navbar-translate {
+    -webkit-transform: translateX(-230px);
+    -moz-transform: translateX(-230px);
+    -o-transform: translateX(-230px);
+    -ms-transform: translateX(-230px);
+    transform: translateX(-230px);
+  }
+  .wrapper .navbar-collapse {
+    display: none;
+  }
+  .register-page.full-screen .page-header .container {
+    margin-top: 30%;
+  }
+  .dropdown.show .dropdown-menu,
+  .dropdown .dropdown-menu {
+    border: 0;
+    transition: none;
+    -webkit-box-shadow: none;
+    box-shadow: none;
+    width: auto;
+    height: auto;
+  }
+  .dropdown.show .dropdown-menu .dropdown-item:hover,
+  .dropdown.show .dropdown-menu .dropdown-item:focus,
+  .dropdown .dropdown-menu .dropdown-item:hover,
+  .dropdown .dropdown-menu .dropdown-item:focus {
+    background-color: transparent;
+    border-radius: 0;
+  }
+  .dropdown.show .dropdown-menu .dropdown-item a:hover,
+  .dropdown.show .dropdown-menu .dropdown-item a:focus,
+  .dropdown .dropdown-menu .dropdown-item a:hover,
+  .dropdown .dropdown-menu .dropdown-item a:focus {
+    color: #403D39;
+  }
+  .dropdown.show .dropdown-menu:before,
+  .dropdown.show .dropdown-menu:after,
+  .dropdown .dropdown-menu:before,
+  .dropdown .dropdown-menu:after {
+    display: none;
+  }
+  .dropdown .dropdown-menu {
+    display: none;
+  }
+  .dropdown.show .dropdown-menu {
+    display: block;
+    position: static;
+    float: none;
+    background: transparent !important;
+  }
+  .navbar-translate {
+    width: 100%;
+    position: relative;
+    display: flex;
+    -ms-flex-pack: justify !important;
+    justify-content: space-between !important;
+    -ms-flex-align: center;
+    align-items: center;
+    -webkit-transform: translateX(0);
+    -moz-transform: translateX(0);
+    -o-transform: translateX(0);
+    -ms-transform: translateX(0);
+    transform: translateX(0);
+    -webkit-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -moz-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -o-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -ms-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+  }
+  #bodyClick {
+    height: 100%;
+    width: 100%;
+    position: fixed;
+    opacity: 0;
+    top: 0;
+    left: auto;
+    right: 230px;
+    content: "";
+    z-index: 1029;
+    overflow-x: hidden;
+  }
+  .wrapper {
+    -webkit-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -moz-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -o-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -ms-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    left: 0;
+    background-color: white;
+  }
+  .container-cards [class*="col-md-"] {
+    padding-left: 5px;
+    padding-right: 5px;
+  }
+  .container-cards .social-buttons {
+    z-index: 1;
+  }
+  .full-screen.login .page-header {
+    display: grid;
+  }
+  .comments.media-area .media {
+    display: block;
+  }
+  .comments.media-area .media .media-body {
+    margin-left: 2em;
+  }
+  .comments.media-area .media .media-body p {
+    margin-top: 15px;
+  }
+  .section-navbars .navbar-collapse,
+  .section-navigation .navbar-collapse,
+  #navbar-dropdown .navbar-collapse {
+    display: none !important;
+  }
+  .header-4 video {
+    width: auto;
+    height: 100vh;
+  }
+  .subscribe-line .btn.btn-block {
+    width: auto;
+  }
+  .form-control+.form-control-feedback {
+    padding-left: 0 !important;
+  }
+}
+
+@media screen and (min-width: 991px) {
+  .burger-menu .navbar-collapse {
+    position: fixed;
+    display: block;
+    top: 0;
+    height: 100%;
+    width: 230px;
+    right: 0px;
+    z-index: 1032;
+    visibility: visible;
+    background-color: #999;
+    overflow-y: visible;
+    border-top: none;
+    text-align: left;
+    border-left: 1px solid #CCC5B9;
+    padding-right: 0px;
+    padding-left: 40px;
+    padding-top: 15px;
+    -webkit-transform: translateX(230px);
+    -moz-transform: translateX(230px);
+    -o-transform: translateX(230px);
+    -ms-transform: translateX(230px);
+    transform: translateX(230px);
+    -webkit-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -moz-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -o-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -ms-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+  }
+  .burger-menu .navbar-collapse .navbar-nav .nav-item:last-child {
+    border-bottom: 0;
+  }
+  .burger-menu .navbar-collapse .navbar-nav {
+    height: 100%;
+    z-index: 2;
+    position: relative;
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: -ms-flexbox;
+    display: flex;
+    -webkit-box-orient: vertical;
+    -webkit-box-direction: normal;
+    -webkit-flex-direction: column;
+    -ms-flex-direction: column;
+    flex-direction: column;
+  }
+  .burger-menu .navbar-collapse::after {
+    top: 0;
+    left: 0;
+    height: 100%;
+    width: 100%;
+    position: absolute;
+    background-color: #FFFCF5;
+    background-image: linear-gradient(to bottom, transparent 0%, rgba(112, 112, 112, 0) 60%, rgba(186, 186, 186, 0.15) 100%);
+    display: block;
+    content: "";
+    z-index: 1;
+  }
+  .burger-menu .navbar-collapse.has-image::after {
+    top: 0;
+    left: 0;
+    height: 100%;
+    width: 100%;
+    position: absolute;
+    background-color: rgba(17, 17, 17, 0.8);
+    display: block;
+    content: "";
+    z-index: 1;
+  }
+  .burger-menu .navbar .container .navbar-toggler {
+    display: block;
+    margin-top: 20px;
+  }
+  .burger-menu .navbar-translate {
+    width: 100%;
+    position: relative;
+    -webkit-transform: translateX(0);
+    -moz-transform: translateX(0);
+    -o-transform: translateX(0);
+    -ms-transform: translateX(0);
+    transform: translateX(0);
+    -webkit-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -moz-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -o-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -ms-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+  }
+  .burger-menu .wrapper {
+    -webkit-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -moz-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -o-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    -ms-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1);
+    left: 0;
+    background-color: white;
+  }
+  .burger-menu .body .navbar-collapse.collapse {
+    height: 100vh !important;
+  }
+  .burger-menu .navbar-collapse:before,
+  .burger-menu .navbar-collapse:after,
+  .burger-menu .navbar-nav:before,
+  .burger-menu .navbar-nav:after {
+    display: table;
+    content: " ";
+  }
+  .nav-open .burger-menu .navbar-collapse.collapse {
+    -webkit-transform: translateX(0px);
+    -moz-transform: translateX(0px);
+    -o-transform: translateX(0px);
+    -ms-transform: translateX(0px);
+    transform: translateX(0px);
+  }
+  .nav-open .burger-menu .wrapper {
+    left: 0;
+    -webkit-transform: translateX(-230px);
+    -moz-transform: translateX(-230px);
+    -o-transform: translateX(-230px);
+    -ms-transform: translateX(-230px);
+    transform: translateX(-230px);
+  }
+  .nav-open .burger-menu .navbar-translate {
+    -webkit-transform: translateX(-230px);
+    -moz-transform: translateX(-230px);
+    -o-transform: translateX(-230px);
+    -ms-transform: translateX(-230px);
+    transform: translateX(-230px);
+  }
+  .burger-menu .dropdown.show .dropdown-menu,
+  .burger-menu .dropdown .dropdown-menu {
+    border: 0;
+    transition: none;
+    -webkit-box-shadow: none;
+    box-shadow: none;
+    width: auto;
+  }
+  .burger-menu .dropdown.show .dropdown-menu .dropdown-item:hover,
+  .burger-menu .dropdown.show .dropdown-menu .dropdown-item:focus,
+  .burger-menu .dropdown .dropdown-menu .dropdown-item:hover,
+  .burger-menu .dropdown .dropdown-menu .dropdown-item:focus {
+    background-color: transparent;
+    border-radius: 0;
+  }
+  .burger-menu .dropdown.show .dropdown-menu .dropdown-item a:hover,
+  .burger-menu .dropdown.show .dropdown-menu .dropdown-item a:focus,
+  .burger-menu .dropdown .dropdown-menu .dropdown-item a:hover,
+  .burger-menu .dropdown .dropdown-menu .dropdown-item a:focus {
+    color: #403D39;
+  }
+  .burger-menu .dropdown.show .dropdown-menu:before,
+  .burger-menu .dropdown.show .dropdown-menu:after,
+  .burger-menu .dropdown .dropdown-menu:before,
+  .burger-menu .dropdown .dropdown-menu:after {
+    display: none;
+  }
+  .burger-menu .dropdown .dropdown-menu {
+    display: none;
+  }
+  .burger-menu .dropdown.show .dropdown-menu {
+    display: block;
+  }
+  .lightbox .modal-dialog {
+    width: 960px;
+  }
+}
+
+@media screen and (min-width: 767px) {
+  .section-sections .section-cols {
+    position: relative;
+    z-index: 1;
+  }
+  .register-page .page-header .container {
+    margin-top: 150px;
+  }
+}
+
+@media (max-width: 1023px) and (min-width: 767px) {
+  .presentation-page .section-content .image-container .area-img {
+    max-width: 190px;
+    max-height: 270px;
+  }
+  .presentation-page .section-content .image-container .info-img {
+    max-width: 190px;
+    max-height: 270px;
+    left: -20%;
+  }
+  .presentation-page .section-content .section-description {
+    margin-top: 0 !important;
+  }
+  .presentation-page .section-components .components-macbook {
+    left: -75px !important;
+  }
+  .presentation-page .section-cards .codrops-header {
+    margin-top: 10px !important;
+  }
+}
+
+@media (max-width: 1367px) and (min-width: 1024px) {
+  .presentation-page .section-components .basic-container {
+    margin-left: 5em;
+  }
+}
+
+@media (max-width: 500px) {
+  .presentation-page .section-header .card {
+    min-height: 230px;
+  }
+  #cards .card-profile {
+    margin-top: 50px;
+  }
+  .pricing-5 .title {
+    text-align: center;
+  }
+  .presentation-page .presentation-title {
+    font-size: 4em;
+  }
+  .presentation-page .title-brand .type {
+    font-size: 12px;
+    padding: 4px 7px;
+    border-radius: 4px;
+    top: 0;
+    font-weight: 600;
+    margin-top: 20px;
+    right: 2px;
+  }
+  .presentation-page .section-cards .codrops-header .description {
+    max-width: 220px;
+  }
+  .register-page .page-header .container .info:first-of-type {
+    margin-top: 50px;
+  }
+}
+
+@media screen and (max-width: 1367px) {
+  .presentation-page .section-cards,
+  .presentation-page .section-components {
+    overflow: hidden;
+  }
+}
+
+@media screen and (min-width: 1025) {
+  .section-sections .section-cols {
+    position: relative;
+    z-index: 1;
+  }
+  .section-sections .section-cols .row:first-of-type {
+    margin-top: 50px;
+    margin-right: -120px;
+    margin-left: -15px;
+    -webkit-transform: translateX(-80px);
+    -moz-transform: translateX(-80px);
+    -o-transform: translateX(-80px);
+    -ms-transform: translateX(-80px);
+    transform: translateX(-80px);
+  }
+  .section-sections .section-cols .row:nth-of-type(2) {
+    margin-left: -100px;
+    margin-right: -15px;
+    transform: translateX(80px);
+  }
+  .section-sections .section-cols .row:nth-of-type(3) {
+    margin-right: -120px;
+    margin-left: 0px;
+    transform: translateX(-120px);
+  }
+  .section-sections .section-cols .row:nth-of-type(4) {
+    margin-right: -100px;
+    margin-left: -15px;
+    transform: translateX(-50px);
+  }
+}
+
+@media only screen and (min-width: 1024px) {
+  .demo-icons ul li {
+    width: 12.5%;
+    float: left;
+    padding: 32px 0;
+  }
+}
+
+@media (max-width: 1200px) {
+  .presentation-page .presentation-title {
+    font-size: 7em;
+  }
+  .presentation-page .title-brand {
+    max-width: 650px;
+  }
+}
+
+@media (max-width: 1200px) {
+  .presentation .section-images .image img {
+    width: 100%;
+  }
+}
+
+@media screen and (max-width: 374px) {
+  .footer.footer-big .copyright .pull-left,
+  .footer.footer-big .copyright .pull-right {
+    float: none !important;
+  }
+  .full-screen.login .card.card-register {
+    margin-bottom: 20px;
+  }
+  .full-screen.login .demo-footer {
+    margin-left: -15px;
+  }
+  .about-us .header-wrapper {
+    height: auto !important;
+  }
+  .presentation-page .section-content .image-container .area-img {
+    max-width: 170px !important;
+  }
+}
+
+/*# sourceMappingURL=kit-free.css.map */

File diff suppressed because it is too large
+ 50 - 0
src/main/resources/static/css/paper-kit.css.map


File diff suppressed because it is too large
+ 15 - 0
src/main/resources/static/css/paper-kit.min.css


BIN
src/main/resources/static/fonts/nucleo-icons.eot


BIN
src/main/resources/static/fonts/nucleo-icons.ttf


BIN
src/main/resources/static/fonts/nucleo-icons.woff


BIN
src/main/resources/static/fonts/nucleo-icons.woff2


BIN
src/main/resources/static/images/author.png


BIN
src/main/resources/static/images/fog-low.png


BIN
src/main/resources/static/images/index-background.jpg


BIN
src/main/resources/static/images/yumin.jpg


File diff suppressed because it is too large
+ 5 - 0
src/main/resources/static/js/core/bootstrap.min.js


File diff suppressed because it is too large
+ 1 - 0
src/main/resources/static/js/core/jquery.min.js


File diff suppressed because it is too large
+ 3 - 0
src/main/resources/static/js/core/popper.min.js


+ 318 - 0
src/main/resources/static/js/paper-kit.js

@@ -0,0 +1,318 @@
+/*!
+
+ =========================================================
+ * Paper Kit - v2.2.0
+ =========================================================
+
+ * Product Page: https://www.creative-tim.com/product/paper-kit
+ * Copyright 2019 Creative Tim (http://www.creative-tim.com)
+
+ * Designed by www.invisionapp.com Coded by www.creative-tim.com
+
+ =========================================================
+
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ */
+
+
+var transparent = true;
+var big_image;
+
+var transparentDemo = true;
+var fixedTop = false;
+
+var navbar_initialized,
+  backgroundOrange = false,
+  toggle_initialized = false;
+
+$(document).ready(function() {
+  window_width = $(window).width();
+  var big_image;
+
+  //  Activate the tooltips
+  if ($('[data-toggle="tooltip"]').length != 0) {
+    $('[data-toggle="tooltip"]').tooltip();
+  }
+
+  //  Activate regular switches
+  if ($("[data-toggle='switch']").length != 0) {
+    $("[data-toggle='switch']").bootstrapSwitch();
+  }
+
+  //  Append modals to <body>
+  if ($(".modal").length != 0) {
+    $('.modal').appendTo('body');
+  }
+
+  // Init noUiSlider
+  pk.initSliders();
+
+  // Init popovers
+  pk.initPopovers();
+
+  // Activate the image for the navbar-collapse
+  pk.initNavbarImage();
+
+  // Navbar color change on scroll
+  if ($('.navbar[color-on-scroll]').length != 0) {
+    $(window).on('scroll', pk.checkScrollForTransparentNavbar);
+  }
+
+  $('.navbar-collapse').click(function() {
+    setTimeout(function() {
+      if (pk.misc.navbar_menu_visible == 1) {
+        $('html').removeClass('nav-open');
+        pk.misc.navbar_menu_visible = 0;
+        $('#bodyClick').remove();
+        setTimeout(function() {
+          $toggle.removeClass('toggled');
+        }, 550);
+      }
+    }, 550);
+  });
+
+  // Change the collor of navbar collapse
+  $('#navbarToggler').on('show.bs.collapse', function() {
+    if ($('nav').hasClass('navbar-transparent') && $(document).scrollTop() < 50) {
+      $('.navbar').addClass('no-transition');
+      $('nav').removeClass('navbar-transparent');
+    }
+  }).on('hidden.bs.collapse', function() {
+    if ($(document).scrollTop() < 50) {
+      $('.navbar').removeClass('no-transition');
+      $('nav:first-of-type').addClass('navbar-transparent');
+    }
+  });
+
+  $navbar = $('.navbar[color-on-scroll]');
+  scroll_distance = $navbar.attr('color-on-scroll') || 500;
+
+  // Check if we have the class "navbar-color-on-scroll" then add the function to remove the class "navbar-transparent" so it will transform to a plain color.
+
+  if ($('.navbar[color-on-scroll]').length != 0) {
+    pk.checkScrollForTransparentNavbar();
+    $(window).on('scroll', pk.checkScroll)
+  }
+
+  $('.form-control').on("focus", function() {
+    $(this).parent('.input-group').addClass("input-group-focus");
+  }).on("blur", function() {
+    $(this).parent(".input-group").removeClass("input-group-focus");
+  });
+
+
+  if (window_width >= 768) {
+    big_image = $('.page-header[data-parallax="true"]');
+
+    if (big_image.length != 0) {
+      $(window).on('scroll', pk.checkScrollForPresentationPage);
+    }
+  }
+  // Activate Carousel
+  $('.carousel').carousel({
+    interval: 4000
+  });
+
+});
+
+$(document).on('click', '.navbar-toggler', function() {
+  $toggle = $(this);
+
+  if (pk.misc.navbar_menu_visible == 1) {
+    $('html').removeClass('nav-open');
+    pk.misc.navbar_menu_visible = 0;
+    $('#bodyClick').remove();
+    setTimeout(function() {
+      $toggle.removeClass('toggled');
+    }, 550);
+  } else {
+    setTimeout(function() {
+      $toggle.addClass('toggled');
+    }, 580);
+    div = '<div id="bodyClick"></div>';
+    $(div).appendTo('body').click(function() {
+      $('html').removeClass('nav-open');
+      pk.misc.navbar_menu_visible = 0;
+      setTimeout(function() {
+        $toggle.removeClass('toggled');
+        $('#bodyClick').remove();
+      }, 550);
+    });
+
+    $('html').addClass('nav-open');
+    pk.misc.navbar_menu_visible = 1;
+  }
+});
+
+pk = {
+  misc: {
+    navbar_menu_visible: 0
+  },
+
+  checkScrollForTransparentNavbar: debounce(function() {
+    if ($(document).scrollTop() > $(".navbar").attr("color-on-scroll")) {
+      if (transparent) {
+        transparent = false;
+        $('.navbar[color-on-scroll]').removeClass('navbar-transparent');
+      }
+    } else {
+      if (!transparent) {
+        transparent = true;
+        $('.navbar[color-on-scroll]').addClass('navbar-transparent');
+      }
+    }
+  }, 17),
+
+  initNavbarImage: function() {
+    var $navbar = $('.navbar').find('.navbar-translate').siblings('.navbar-collapse');
+    var background_image = $navbar.data('nav-image');
+
+    if ($(window).width() < 991 || $('body').hasClass('burger-menu')) {
+      if (background_image != undefined) {
+        $navbar.css('background', "url('" + background_image + "')")
+          .removeAttr('data-nav-image')
+          .css('background-size', "cover")
+          .addClass('has-image');
+      }
+    } else if (background_image != undefined) {
+      $navbar.css('background', "")
+        .attr('data-nav-image', '' + background_image + '')
+        .css('background-size', "")
+        .removeClass('has-image');
+    }
+  },
+
+  initPopovers: function() {
+    if ($('[data-toggle="popover"]').length != 0) {
+      $('body').append('<div class="popover-filter"></div>');
+
+      //    Activate Popovers
+      $('[data-toggle="popover"]').popover().on('show.bs.popover', function() {
+        $('.popover-filter').click(function() {
+          $(this).removeClass('in');
+          $('[data-toggle="popover"]').popover('hide');
+        });
+        $('.popover-filter').addClass('in');
+      }).on('hide.bs.popover', function() {
+        $('.popover-filter').removeClass('in');
+      });
+
+    }
+  },
+
+  initSliders: function() {
+    // Sliders for demo purpose in refine cards section
+    if ($('#sliderRegular').length != 0) {
+      var rangeSlider = document.getElementById('sliderRegular');
+      noUiSlider.create(rangeSlider, {
+        start: [5000],
+        range: {
+          'min': [2000],
+          'max': [10000]
+        }
+      });
+    }
+    if ($('#sliderDouble').length != 0) {
+      var slider = document.getElementById('sliderDouble');
+      noUiSlider.create(slider, {
+        start: [20, 80],
+        connect: true,
+        range: {
+          'min': 0,
+          'max': 100
+        }
+      });
+    }
+
+  },
+
+
+  // Javascript for the parallax
+
+  checkScroll: debounce(function() {
+    big_image = $('.page-header[data-parallax="true"]');
+    oVal = ($(window).scrollTop() / 3);
+    big_image.css({
+      'transform': 'translate3d(0,' + oVal + 'px,0)',
+      '-webkit-transform': 'translate3d(0,' + oVal + 'px,0)',
+      '-ms-transform': 'translate3d(0,' + oVal + 'px,0)',
+      '-o-transform': 'translate3d(0,' + oVal + 'px,0)'
+    });
+  }, 4),
+}
+
+demo = {
+  initPickColor: function() {
+    $('.pick-class-label').click(function() {
+      var new_class = $(this).attr('new-class');
+      var old_class = $('#display-buttons').attr('data-class');
+      var display_div = $('#display-buttons');
+      if (display_div.length) {
+        var display_buttons = display_div.find('.btn');
+        display_buttons.removeClass(old_class);
+        display_buttons.addClass(new_class);
+        display_div.attr('data-class', new_class);
+      }
+    });
+  }
+}
+
+// Returns a function, that, as long as it continues to be invoked, will not
+// be triggered. The function will be called after it stops being called for
+// N milliseconds. If `immediate` is passed, trigger the function on the
+// leading edge, instead of the trailing.
+
+function debounce(func, wait, immediate) {
+  var timeout;
+  return function() {
+    var context = this,
+      args = arguments;
+    clearTimeout(timeout);
+    timeout = setTimeout(function() {
+      timeout = null;
+      if (!immediate) func.apply(context, args);
+    }, wait);
+    if (immediate && !timeout) func.apply(context, args);
+  };
+};
+
+function hasScrolled() {
+  var st = $(this).scrollTop();
+  // Make sure they scroll more than delta
+  if (Math.abs(lastScrollTop - st) <= delta)
+    return;
+
+  // If they scrolled down and are past the navbar, add class .nav-up.
+  // This is necessary so you never see what is "behind" the navbar.
+  if (st > lastScrollTop && st > navbarHeight) {
+    // Scroll Down
+    $('.navbar.nav-down').removeClass('nav-down').addClass('nav-up');
+  } else {
+    // Scroll Up
+    if (st + $(window).height() < $(document).height()) {
+      $('.navbar.nav-up').removeClass('nav-up').addClass('nav-down');
+    }
+  }
+
+  lastScrollTop = st;
+};
+
+// Returns a function, that, as long as it continues to be invoked, will not
+// be triggered. The function will be called after it stops being called for
+// N milliseconds. If `immediate` is passed, trigger the function on the
+// leading edge, instead of the trailing.
+
+function debounce(func, wait, immediate) {
+  var timeout;
+  return function() {
+    var context = this,
+      args = arguments;
+    clearTimeout(timeout);
+    timeout = setTimeout(function() {
+      timeout = null;
+      if (!immediate) func.apply(context, args);
+    }, wait);
+    if (immediate && !timeout) func.apply(context, args);
+  };
+};

File diff suppressed because it is too large
+ 0 - 0
src/main/resources/static/js/paper-kit.js.map


File diff suppressed because it is too large
+ 0 - 0
src/main/resources/static/js/paper-kit.min.js


+ 2707 - 0
src/main/resources/static/js/plugins/bootstrap-datepicker.js

@@ -0,0 +1,2707 @@
+/*! version : 4.17.47
+ =========================================================
+ bootstrap-datetimejs
+ https://github.com/Eonasdan/bootstrap-datetimepicker
+ Copyright (c) 2015 Jonathan Peterson
+ =========================================================
+ */
+/*
+ The MIT License (MIT)
+
+ Copyright (c) 2015 Jonathan Peterson
+
+ 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.
+ */
+/*global define:false */
+/*global exports:false */
+/*global require:false */
+/*global jQuery:false */
+/*global moment:false */
+(function(factory) {
+  'use strict';
+  if (typeof define === 'function' && define.amd) {
+    // AMD is used - Register as an anonymous module.
+    define(['jquery', 'moment'], factory);
+  } else if (typeof exports === 'object') {
+    module.exports = factory(require('jquery'), require('moment'));
+  } else {
+    // Neither AMD nor CommonJS used. Use global variables.
+    if (typeof jQuery === 'undefined') {
+      throw 'bootstrap-datetimepicker requires jQuery to be loaded first';
+    }
+    if (typeof moment === 'undefined') {
+      throw 'bootstrap-datetimepicker requires Moment.js to be loaded first';
+    }
+    factory(jQuery, moment);
+  }
+}(function($, moment) {
+  'use strict';
+  if (!moment) {
+    throw new Error('bootstrap-datetimepicker requires Moment.js to be loaded first');
+  }
+
+  var dateTimePicker = function(element, options) {
+    var picker = {},
+      date,
+      viewDate,
+      unset = true,
+      input,
+      component = false,
+      widget = false,
+      use24Hours,
+      minViewModeNumber = 0,
+      actualFormat,
+      parseFormats,
+      currentViewMode,
+      datePickerModes = [{
+          clsName: 'days',
+          navFnc: 'M',
+          navStep: 1
+        },
+        {
+          clsName: 'months',
+          navFnc: 'y',
+          navStep: 1
+        },
+        {
+          clsName: 'years',
+          navFnc: 'y',
+          navStep: 10
+        },
+        {
+          clsName: 'decades',
+          navFnc: 'y',
+          navStep: 100
+        }
+      ],
+      viewModes = ['days', 'months', 'years', 'decades'],
+      verticalModes = ['top', 'bottom', 'auto'],
+      horizontalModes = ['left', 'right', 'auto'],
+      toolbarPlacements = ['default', 'top', 'bottom'],
+      keyMap = {
+        'up': 38,
+        38: 'up',
+        'down': 40,
+        40: 'down',
+        'left': 37,
+        37: 'left',
+        'right': 39,
+        39: 'right',
+        'tab': 9,
+        9: 'tab',
+        'escape': 27,
+        27: 'escape',
+        'enter': 13,
+        13: 'enter',
+        'pageUp': 33,
+        33: 'pageUp',
+        'pageDown': 34,
+        34: 'pageDown',
+        'shift': 16,
+        16: 'shift',
+        'control': 17,
+        17: 'control',
+        'space': 32,
+        32: 'space',
+        't': 84,
+        84: 't',
+        'delete': 46,
+        46: 'delete'
+      },
+      keyState = {},
+
+      /********************************************************************************
+       *
+       * Private functions
+       *
+       ********************************************************************************/
+
+      hasTimeZone = function() {
+        return moment.tz !== undefined && options.timeZone !== undefined && options.timeZone !== null && options.timeZone !== '';
+      },
+
+      getMoment = function(d) {
+        var returnMoment;
+
+        if (d === undefined || d === null) {
+          returnMoment = moment(); //TODO should this use format? and locale?
+        } else if (moment.isDate(d) || moment.isMoment(d)) {
+          // If the date that is passed in is already a Date() or moment() object,
+          // pass it directly to moment.
+          returnMoment = moment(d);
+        } else if (hasTimeZone()) { // There is a string to parse and a default time zone
+          // parse with the tz function which takes a default time zone if it is not in the format string
+          returnMoment = moment.tz(d, parseFormats, options.useStrict, options.timeZone);
+        } else {
+          returnMoment = moment(d, parseFormats, options.useStrict);
+        }
+
+        if (hasTimeZone()) {
+          returnMoment.tz(options.timeZone);
+        }
+
+        return returnMoment;
+      },
+
+      isEnabled = function(granularity) {
+        if (typeof granularity !== 'string' || granularity.length > 1) {
+          throw new TypeError('isEnabled expects a single character string parameter');
+        }
+        switch (granularity) {
+          case 'y':
+            return actualFormat.indexOf('Y') !== -1;
+          case 'M':
+            return actualFormat.indexOf('M') !== -1;
+          case 'd':
+            return actualFormat.toLowerCase().indexOf('d') !== -1;
+          case 'h':
+          case 'H':
+            return actualFormat.toLowerCase().indexOf('h') !== -1;
+          case 'm':
+            return actualFormat.indexOf('m') !== -1;
+          case 's':
+            return actualFormat.indexOf('s') !== -1;
+          default:
+            return false;
+        }
+      },
+
+      hasTime = function() {
+        return (isEnabled('h') || isEnabled('m') || isEnabled('s'));
+      },
+
+      hasDate = function() {
+        return (isEnabled('y') || isEnabled('M') || isEnabled('d'));
+      },
+
+      getDatePickerTemplate = function() {
+        var headTemplate = $('<thead>')
+          .append($('<tr>')
+            .append($('<th>').addClass('prev').attr('data-action', 'previous')
+              .append($('<span>').addClass(options.icons.previous))
+            )
+            .append($('<th>').addClass('picker-switch').attr('data-action', 'pickerSwitch').attr('colspan', (options.calendarWeeks ? '6' : '5')))
+            .append($('<th>').addClass('next').attr('data-action', 'next')
+              .append($('<span>').addClass(options.icons.next))
+            )
+          ),
+          contTemplate = $('<tbody>')
+          .append($('<tr>')
+            .append($('<td>').attr('colspan', (options.calendarWeeks ? '8' : '7')))
+          );
+
+        return [
+          $('<div>').addClass('datepicker-days')
+          .append($('<table>').addClass('table-condensed')
+            .append(headTemplate)
+            .append($('<tbody>'))
+          ),
+          $('<div>').addClass('datepicker-months')
+          .append($('<table>').addClass('table-condensed')
+            .append(headTemplate.clone())
+            .append(contTemplate.clone())
+          ),
+          $('<div>').addClass('datepicker-years')
+          .append($('<table>').addClass('table-condensed')
+            .append(headTemplate.clone())
+            .append(contTemplate.clone())
+          ),
+          $('<div>').addClass('datepicker-decades')
+          .append($('<table>').addClass('table-condensed')
+            .append(headTemplate.clone())
+            .append(contTemplate.clone())
+          )
+        ];
+      },
+
+      getTimePickerMainTemplate = function() {
+        var topRow = $('<tr>'),
+          middleRow = $('<tr>'),
+          bottomRow = $('<tr>');
+
+        if (isEnabled('h')) {
+          topRow.append($('<td>')
+            .append($('<a>').attr({
+              href: '#',
+              tabindex: '-1',
+              'title': options.tooltips.incrementHour
+            }).addClass('btn').attr('data-action', 'incrementHours').append($('<span>').addClass(options.icons.up))));
+          middleRow.append($('<td>')
+            .append($('<span>').addClass('timepicker-hour').attr({
+              'data-time-component': 'hours',
+              'title': options.tooltips.pickHour
+            }).attr('data-action', 'showHours')));
+          bottomRow.append($('<td>')
+            .append($('<a>').attr({
+              href: '#',
+              tabindex: '-1',
+              'title': options.tooltips.decrementHour
+            }).addClass('btn').attr('data-action', 'decrementHours').append($('<span>').addClass(options.icons.down))));
+        }
+        if (isEnabled('m')) {
+          if (isEnabled('h')) {
+            topRow.append($('<td>').addClass('separator'));
+            middleRow.append($('<td>').addClass('separator').html(':'));
+            bottomRow.append($('<td>').addClass('separator'));
+          }
+          topRow.append($('<td>')
+            .append($('<a>').attr({
+                href: '#',
+                tabindex: '-1',
+                'title': options.tooltips.incrementMinute
+              }).addClass('btn').attr('data-action', 'incrementMinutes')
+              .append($('<span>').addClass(options.icons.up))));
+          middleRow.append($('<td>')
+            .append($('<span>').addClass('timepicker-minute').attr({
+              'data-time-component': 'minutes',
+              'title': options.tooltips.pickMinute
+            }).attr('data-action', 'showMinutes')));
+          bottomRow.append($('<td>')
+            .append($('<a>').attr({
+                href: '#',
+                tabindex: '-1',
+                'title': options.tooltips.decrementMinute
+              }).addClass('btn').attr('data-action', 'decrementMinutes')
+              .append($('<span>').addClass(options.icons.down))));
+        }
+        if (isEnabled('s')) {
+          if (isEnabled('m')) {
+            topRow.append($('<td>').addClass('separator'));
+            middleRow.append($('<td>').addClass('separator').html(':'));
+            bottomRow.append($('<td>').addClass('separator'));
+          }
+          topRow.append($('<td>')
+            .append($('<a>').attr({
+                href: '#',
+                tabindex: '-1',
+                'title': options.tooltips.incrementSecond
+              }).addClass('btn btn-link').attr('data-action', 'incrementSeconds')
+              .append($('<span>').addClass(options.icons.up))));
+          middleRow.append($('<td>')
+            .append($('<span>').addClass('timepicker-second').attr({
+              'data-time-component': 'seconds',
+              'title': options.tooltips.pickSecond
+            }).attr('data-action', 'showSeconds')));
+          bottomRow.append($('<td>')
+            .append($('<a>').attr({
+                href: '#',
+                tabindex: '-1',
+                'title': options.tooltips.decrementSecond
+              }).addClass('btn btn-link').attr('data-action', 'decrementSeconds')
+              .append($('<span>').addClass(options.icons.down))));
+        }
+
+        if (!use24Hours) {
+          topRow.append($('<td>').addClass('separator'));
+          middleRow.append($('<td>')
+            .append($('<button>').addClass('btn btn-outline-primary btn-round').attr({
+              'data-action': 'togglePeriod',
+              tabindex: '-1',
+              'title': options.tooltips.togglePeriod
+            })));
+          bottomRow.append($('<td>').addClass('separator'));
+        }
+
+        return $('<div>').addClass('timepicker-picker')
+          .append($('<table>').addClass('table-condensed')
+            .append([topRow, middleRow, bottomRow]));
+      },
+
+      getTimePickerTemplate = function() {
+        var hoursView = $('<div>').addClass('timepicker-hours')
+          .append($('<table>').addClass('table-condensed')),
+          minutesView = $('<div>').addClass('timepicker-minutes')
+          .append($('<table>').addClass('table-condensed')),
+          secondsView = $('<div>').addClass('timepicker-seconds')
+          .append($('<table>').addClass('table-condensed')),
+          ret = [getTimePickerMainTemplate()];
+
+        if (isEnabled('h')) {
+          ret.push(hoursView);
+        }
+        if (isEnabled('m')) {
+          ret.push(minutesView);
+        }
+        if (isEnabled('s')) {
+          ret.push(secondsView);
+        }
+
+        return ret;
+      },
+
+      getToolbar = function() {
+        var row = [];
+        if (options.showTodayButton) {
+          row.push($('<td>').append($('<a>').attr({
+            'data-action': 'today',
+            'title': options.tooltips.today
+          }).append($('<span>').addClass(options.icons.today))));
+        }
+        if (!options.sideBySide && hasDate() && hasTime()) {
+          row.push($('<td>').append($('<a>').attr({
+            'data-action': 'togglePicker',
+            'title': options.tooltips.selectTime
+          }).append($('<span>').addClass(options.icons.time))));
+        }
+        if (options.showClear) {
+          row.push($('<td>').append($('<a>').attr({
+            'data-action': 'clear',
+            'title': options.tooltips.clear
+          }).append($('<span>').addClass(options.icons.clear))));
+        }
+        if (options.showClose) {
+          row.push($('<td>').append($('<a>').attr({
+            'data-action': 'close',
+            'title': options.tooltips.close
+          }).append($('<span>').addClass(options.icons.close))));
+        }
+        return $('<table>').addClass('table-condensed').append($('<tbody>').append($('<tr>').append(row)));
+      },
+
+      getTemplate = function() {
+        var template = $('<div>').addClass('bootstrap-datetimepicker-widget dropdown-menu'),
+          dateView = $('<div>').addClass('datepicker').append(getDatePickerTemplate()),
+          timeView = $('<div>').addClass('timepicker').append(getTimePickerTemplate()),
+          content = $('<ul>').addClass('list-unstyled'),
+          toolbar = $('<li>').addClass('picker-switch' + (options.collapse ? ' accordion-toggle' : '')).append(getToolbar());
+
+        if (options.inline) {
+          template.removeClass('dropdown-menu');
+        }
+
+        if (use24Hours) {
+          template.addClass('usetwentyfour');
+        }
+
+        if (isEnabled('s') && !use24Hours) {
+          template.addClass('wider');
+        }
+
+        if (options.sideBySide && hasDate() && hasTime()) {
+          template.addClass('timepicker-sbs');
+          if (options.toolbarPlacement === 'top') {
+            template.append(toolbar);
+          }
+          template.append(
+            $('<div>').addClass('row')
+            .append(dateView.addClass('col-md-6'))
+            .append(timeView.addClass('col-md-6'))
+          );
+          if (options.toolbarPlacement === 'bottom') {
+            template.append(toolbar);
+          }
+          return template;
+        }
+
+        if (options.toolbarPlacement === 'top') {
+          content.append(toolbar);
+        }
+        if (hasDate()) {
+          content.append($('<li>').addClass((options.collapse && hasTime() ? 'collapse show' : '')).append(dateView));
+        }
+        if (options.toolbarPlacement === 'default') {
+          content.append(toolbar);
+        }
+        if (hasTime()) {
+          content.append($('<li>').addClass((options.collapse && hasDate() ? 'collapse' : '')).append(timeView));
+        }
+        if (options.toolbarPlacement === 'bottom') {
+          content.append(toolbar);
+        }
+        return template.append(content);
+      },
+
+      dataToOptions = function() {
+        var eData,
+          dataOptions = {};
+
+        if (element.is('input') || options.inline) {
+          eData = element.data();
+        } else {
+          eData = element.find('input').data();
+        }
+
+        if (eData.dateOptions && eData.dateOptions instanceof Object) {
+          dataOptions = $.extend(true, dataOptions, eData.dateOptions);
+        }
+
+        $.each(options, function(key) {
+          var attributeName = 'date' + key.charAt(0).toUpperCase() + key.slice(1);
+          if (eData[attributeName] !== undefined) {
+            dataOptions[key] = eData[attributeName];
+          }
+        });
+        return dataOptions;
+      },
+
+      place = function() {
+        var position = (component || element).position(),
+          offset = (component || element).offset(),
+          vertical = options.widgetPositioning.vertical,
+          horizontal = options.widgetPositioning.horizontal,
+          parent;
+
+        if (options.widgetParent) {
+          parent = options.widgetParent.append(widget);
+        } else if (element.is('input')) {
+          parent = element.after(widget).parent();
+        } else if (options.inline) {
+          parent = element.append(widget);
+          return;
+        } else {
+          parent = element;
+          element.children().first().after(widget);
+        }
+
+        // Top and bottom logic
+        if (vertical === 'auto') {
+          if (offset.top + widget.height() * 1.5 >= $(window).height() + $(window).scrollTop() &&
+            widget.height() + element.outerHeight() < offset.top) {
+            vertical = 'top';
+          } else {
+            vertical = 'bottom';
+          }
+        }
+
+        // Left and right logic
+        if (horizontal === 'auto') {
+          if (parent.width() < offset.left + widget.outerWidth() / 2 &&
+            offset.left + widget.outerWidth() > $(window).width()) {
+            horizontal = 'right';
+          } else {
+            horizontal = 'left';
+          }
+        }
+
+        if (vertical === 'top') {
+          widget.addClass('top').removeClass('bottom');
+        } else {
+          widget.addClass('bottom').removeClass('top');
+        }
+
+        if (horizontal === 'right') {
+          widget.addClass('pull-right');
+        } else {
+          widget.removeClass('pull-right');
+        }
+
+        // find the first parent element that has a non-static css positioning
+        if (parent.css('position') === 'static') {
+          parent = parent.parents().filter(function() {
+            return $(this).css('position') !== 'static';
+          }).first();
+        }
+
+        if (parent.length === 0) {
+          throw new Error('datetimepicker component should be placed within a non-static positioned container');
+        }
+
+        widget.css({
+          top: vertical === 'top' ? 'auto' : position.top + element.outerHeight(),
+          bottom: vertical === 'top' ? parent.outerHeight() - (parent === element ? 0 : position.top) : 'auto',
+          left: horizontal === 'left' ? (parent === element ? 0 : position.left) : 'auto',
+          right: horizontal === 'left' ? 'auto' : parent.outerWidth() - element.outerWidth() - (parent === element ? 0 : position.left)
+        });
+
+        // Creative Tim Changes - we add after 180 ms the ".open" class, in this way the animations will be the same with the other dropdowns from the
+        setTimeout(function() {
+          widget.addClass('open');
+        }, 10);
+
+      },
+
+      notifyEvent = function(e) {
+        if (e.type === 'dp.change' && ((e.date && e.date.isSame(e.oldDate)) || (!e.date && !e.oldDate))) {
+          return;
+        }
+        element.trigger(e);
+      },
+
+      viewUpdate = function(e) {
+        if (e === 'y') {
+          e = 'YYYY';
+        }
+        notifyEvent({
+          type: 'dp.update',
+          change: e,
+          viewDate: viewDate.clone()
+        });
+      },
+
+      showMode = function(dir) {
+        if (!widget) {
+          return;
+        }
+        if (dir) {
+          currentViewMode = Math.max(minViewModeNumber, Math.min(3, currentViewMode + dir));
+        }
+        widget.find('.datepicker > div').hide().filter('.datepicker-' + datePickerModes[currentViewMode].clsName).show();
+      },
+
+      fillDow = function() {
+        var row = $('<tr>'),
+          currentDate = viewDate.clone().startOf('w').startOf('d');
+
+        if (options.calendarWeeks === true) {
+          row.append($('<th>').addClass('cw').text('#'));
+        }
+
+        while (currentDate.isBefore(viewDate.clone().endOf('w'))) {
+          row.append($('<th>').addClass('dow').text(currentDate.format('dd')));
+          currentDate.add(1, 'd');
+        }
+        widget.find('.datepicker-days thead').append(row);
+      },
+
+      isInDisabledDates = function(testDate) {
+        return options.disabledDates[testDate.format('YYYY-MM-DD')] === true;
+      },
+
+      isInEnabledDates = function(testDate) {
+        return options.enabledDates[testDate.format('YYYY-MM-DD')] === true;
+      },
+
+      isInDisabledHours = function(testDate) {
+        return options.disabledHours[testDate.format('H')] === true;
+      },
+
+      isInEnabledHours = function(testDate) {
+        return options.enabledHours[testDate.format('H')] === true;
+      },
+
+      isValid = function(targetMoment, granularity) {
+        if (!targetMoment.isValid()) {
+          return false;
+        }
+        if (options.disabledDates && granularity === 'd' && isInDisabledDates(targetMoment)) {
+          return false;
+        }
+        if (options.enabledDates && granularity === 'd' && !isInEnabledDates(targetMoment)) {
+          return false;
+        }
+        if (options.minDate && targetMoment.isBefore(options.minDate, granularity)) {
+          return false;
+        }
+        if (options.maxDate && targetMoment.isAfter(options.maxDate, granularity)) {
+          return false;
+        }
+        if (options.daysOfWeekDisabled && granularity === 'd' && options.daysOfWeekDisabled.indexOf(targetMoment.day()) !== -1) {
+          return false;
+        }
+        if (options.disabledHours && (granularity === 'h' || granularity === 'm' || granularity === 's') && isInDisabledHours(targetMoment)) {
+          return false;
+        }
+        if (options.enabledHours && (granularity === 'h' || granularity === 'm' || granularity === 's') && !isInEnabledHours(targetMoment)) {
+          return false;
+        }
+        if (options.disabledTimeIntervals && (granularity === 'h' || granularity === 'm' || granularity === 's')) {
+          var found = false;
+          $.each(options.disabledTimeIntervals, function() {
+            if (targetMoment.isBetween(this[0], this[1])) {
+              found = true;
+              return false;
+            }
+          });
+          if (found) {
+            return false;
+          }
+        }
+        return true;
+      },
+
+      fillMonths = function() {
+        var spans = [],
+          monthsShort = viewDate.clone().startOf('y').startOf('d');
+        while (monthsShort.isSame(viewDate, 'y')) {
+          spans.push($('<span>').attr('data-action', 'selectMonth').addClass('month').text(monthsShort.format('MMM')));
+          monthsShort.add(1, 'M');
+        }
+        widget.find('.datepicker-months td').empty().append(spans);
+      },
+
+      updateMonths = function() {
+        var monthsView = widget.find('.datepicker-months'),
+          monthsViewHeader = monthsView.find('th'),
+          months = monthsView.find('tbody').find('span');
+
+        monthsViewHeader.eq(0).find('span').attr('title', options.tooltips.prevYear);
+        monthsViewHeader.eq(1).attr('title', options.tooltips.selectYear);
+        monthsViewHeader.eq(2).find('span').attr('title', options.tooltips.nextYear);
+
+        monthsView.find('.disabled').removeClass('disabled');
+
+        if (!isValid(viewDate.clone().subtract(1, 'y'), 'y')) {
+          monthsViewHeader.eq(0).addClass('disabled');
+        }
+
+        monthsViewHeader.eq(1).text(viewDate.year());
+
+        if (!isValid(viewDate.clone().add(1, 'y'), 'y')) {
+          monthsViewHeader.eq(2).addClass('disabled');
+        }
+
+        months.removeClass('active');
+        if (date.isSame(viewDate, 'y') && !unset) {
+          months.eq(date.month()).addClass('active');
+        }
+
+        months.each(function(index) {
+          if (!isValid(viewDate.clone().month(index), 'M')) {
+            $(this).addClass('disabled');
+          }
+        });
+      },
+
+      updateYears = function() {
+        var yearsView = widget.find('.datepicker-years'),
+          yearsViewHeader = yearsView.find('th'),
+          startYear = viewDate.clone().subtract(5, 'y'),
+          endYear = viewDate.clone().add(6, 'y'),
+          html = '';
+
+        yearsViewHeader.eq(0).find('span').attr('title', options.tooltips.prevDecade);
+        yearsViewHeader.eq(1).attr('title', options.tooltips.selectDecade);
+        yearsViewHeader.eq(2).find('span').attr('title', options.tooltips.nextDecade);
+
+        yearsView.find('.disabled').removeClass('disabled');
+
+        if (options.minDate && options.minDate.isAfter(startYear, 'y')) {
+          yearsViewHeader.eq(0).addClass('disabled');
+        }
+
+        yearsViewHeader.eq(1).text(startYear.year() + '-' + endYear.year());
+
+        if (options.maxDate && options.maxDate.isBefore(endYear, 'y')) {
+          yearsViewHeader.eq(2).addClass('disabled');
+        }
+
+        while (!startYear.isAfter(endYear, 'y')) {
+          html += '<span data-action="selectYear" class="year' + (startYear.isSame(date, 'y') && !unset ? ' active' : '') + (!isValid(startYear, 'y') ? ' disabled' : '') + '">' + startYear.year() + '</span>';
+          startYear.add(1, 'y');
+        }
+
+        yearsView.find('td').html(html);
+      },
+
+      updateDecades = function() {
+        var decadesView = widget.find('.datepicker-decades'),
+          decadesViewHeader = decadesView.find('th'),
+          startDecade = moment({
+            y: viewDate.year() - (viewDate.year() % 100) - 1
+          }),
+          endDecade = startDecade.clone().add(100, 'y'),
+          startedAt = startDecade.clone(),
+          minDateDecade = false,
+          maxDateDecade = false,
+          endDecadeYear,
+          html = '';
+
+        decadesViewHeader.eq(0).find('span').attr('title', options.tooltips.prevCentury);
+        decadesViewHeader.eq(2).find('span').attr('title', options.tooltips.nextCentury);
+
+        decadesView.find('.disabled').removeClass('disabled');
+
+        if (startDecade.isSame(moment({
+            y: 1900
+          })) || (options.minDate && options.minDate.isAfter(startDecade, 'y'))) {
+          decadesViewHeader.eq(0).addClass('disabled');
+        }
+
+        decadesViewHeader.eq(1).text(startDecade.year() + '-' + endDecade.year());
+
+        if (startDecade.isSame(moment({
+            y: 2000
+          })) || (options.maxDate && options.maxDate.isBefore(endDecade, 'y'))) {
+          decadesViewHeader.eq(2).addClass('disabled');
+        }
+
+        while (!startDecade.isAfter(endDecade, 'y')) {
+          endDecadeYear = startDecade.year() + 12;
+          minDateDecade = options.minDate && options.minDate.isAfter(startDecade, 'y') && options.minDate.year() <= endDecadeYear;
+          maxDateDecade = options.maxDate && options.maxDate.isAfter(startDecade, 'y') && options.maxDate.year() <= endDecadeYear;
+          html += '<span data-action="selectDecade" class="decade' + (date.isAfter(startDecade) && date.year() <= endDecadeYear ? ' active' : '') +
+            (!isValid(startDecade, 'y') && !minDateDecade && !maxDateDecade ? ' disabled' : '') + '" data-selection="' + (startDecade.year() + 6) + '">' + (startDecade.year() + 1) + ' - ' + (startDecade.year() + 12) + '</span>';
+          startDecade.add(12, 'y');
+        }
+        html += '<span></span><span></span><span></span>'; //push the dangling block over, at least this way it's even
+
+        decadesView.find('td').html(html);
+        decadesViewHeader.eq(1).text((startedAt.year() + 1) + '-' + (startDecade.year()));
+      },
+
+      fillDate = function() {
+        var daysView = widget.find('.datepicker-days'),
+          daysViewHeader = daysView.find('th'),
+          currentDate,
+          html = [],
+          row,
+          clsNames = [],
+          i;
+
+        if (!hasDate()) {
+          return;
+        }
+
+        daysViewHeader.eq(0).find('span').attr('title', options.tooltips.prevMonth);
+        daysViewHeader.eq(1).attr('title', options.tooltips.selectMonth);
+        daysViewHeader.eq(2).find('span').attr('title', options.tooltips.nextMonth);
+
+        daysView.find('.disabled').removeClass('disabled');
+        daysViewHeader.eq(1).text(viewDate.format(options.dayViewHeaderFormat));
+
+        if (!isValid(viewDate.clone().subtract(1, 'M'), 'M')) {
+          daysViewHeader.eq(0).addClass('disabled');
+        }
+        if (!isValid(viewDate.clone().add(1, 'M'), 'M')) {
+          daysViewHeader.eq(2).addClass('disabled');
+        }
+
+        currentDate = viewDate.clone().startOf('M').startOf('w').startOf('d');
+
+        for (i = 0; i < 42; i++) { //always display 42 days (should show 6 weeks)
+          if (currentDate.weekday() === 0) {
+            row = $('<tr>');
+            if (options.calendarWeeks) {
+              row.append('<td class="cw">' + currentDate.week() + '</td>');
+            }
+            html.push(row);
+          }
+          clsNames = ['day'];
+          if (currentDate.isBefore(viewDate, 'M')) {
+            clsNames.push('old');
+          }
+          if (currentDate.isAfter(viewDate, 'M')) {
+            clsNames.push('new');
+          }
+          if (currentDate.isSame(date, 'd') && !unset) {
+            clsNames.push('active');
+          }
+          if (!isValid(currentDate, 'd')) {
+            clsNames.push('disabled');
+          }
+          if (currentDate.isSame(getMoment(), 'd')) {
+            clsNames.push('today');
+          }
+          if (currentDate.day() === 0 || currentDate.day() === 6) {
+            clsNames.push('weekend');
+          }
+          notifyEvent({
+            type: 'dp.classify',
+            date: currentDate,
+            classNames: clsNames
+          });
+          // Creative Tim - we added a div inside each td for design purposes
+          row.append('<td data-action="selectDay" data-day="' + currentDate.format('L') + '" class="' + clsNames.join(' ') + '"><div>' + currentDate.date() + '</div></td>');
+          currentDate.add(1, 'd');
+        }
+
+        daysView.find('tbody').empty().append(html);
+
+        updateMonths();
+
+        updateYears();
+
+        updateDecades();
+      },
+
+      fillHours = function() {
+        var table = widget.find('.timepicker-hours table'),
+          currentHour = viewDate.clone().startOf('d'),
+          html = [],
+          row = $('<tr>');
+
+        if (viewDate.hour() > 11 && !use24Hours) {
+          currentHour.hour(12);
+        }
+        while (currentHour.isSame(viewDate, 'd') && (use24Hours || (viewDate.hour() < 12 && currentHour.hour() < 12) || viewDate.hour() > 11)) {
+          if (currentHour.hour() % 4 === 0) {
+            row = $('<tr>');
+            html.push(row);
+          }
+          // Creative Tim - we added a div inside each class hour for design purposes
+          row.append('<td data-action="selectHour" class="hour' + (!isValid(currentHour, 'h') ? ' disabled' : '') + '"><div>' + currentHour.format(use24Hours ? 'HH' : 'hh') + '</div></td>');
+          currentHour.add(1, 'h');
+        }
+        table.empty().append(html);
+      },
+
+      fillMinutes = function() {
+        var table = widget.find('.timepicker-minutes table'),
+          currentMinute = viewDate.clone().startOf('h'),
+          html = [],
+          row = $('<tr>'),
+          step = options.stepping === 1 ? 5 : options.stepping;
+
+        while (viewDate.isSame(currentMinute, 'h')) {
+          if (currentMinute.minute() % (step * 4) === 0) {
+            row = $('<tr>');
+            html.push(row);
+          }
+          // Creative Tim - we added a div inside each class minute for design purposes
+          row.append('<td data-action="selectMinute" class="minute' + (!isValid(currentMinute, 'm') ? ' disabled' : '') + '"><div>' + currentMinute.format('mm') + '</div></td>');
+          currentMinute.add(step, 'm');
+        }
+        table.empty().append(html);
+      },
+
+      fillSeconds = function() {
+        var table = widget.find('.timepicker-seconds table'),
+          currentSecond = viewDate.clone().startOf('m'),
+          html = [],
+          row = $('<tr>');
+
+        while (viewDate.isSame(currentSecond, 'm')) {
+          if (currentSecond.second() % 20 === 0) {
+            row = $('<tr>');
+            html.push(row);
+          }
+          // Creative Tim - we added a div inside each class seconds for design purposes
+          row.append('<td data-action="selectSecond" class="second' + (!isValid(currentSecond, 's') ? ' disabled' : '') + '"><div>' + currentSecond.format('ss') + '</div></td>');
+          currentSecond.add(5, 's');
+        }
+
+        table.empty().append(html);
+      },
+
+      fillTime = function() {
+        var toggle, newDate, timeComponents = widget.find('.timepicker span[data-time-component]');
+
+        if (!use24Hours) {
+          toggle = widget.find('.timepicker [data-action=togglePeriod]');
+          newDate = date.clone().add((date.hours() >= 12) ? -12 : 12, 'h');
+
+          toggle.text(date.format('A'));
+
+          if (isValid(newDate, 'h')) {
+            toggle.removeClass('disabled');
+          } else {
+            toggle.addClass('disabled');
+          }
+        }
+        timeComponents.filter('[data-time-component=hours]').text(date.format(use24Hours ? 'HH' : 'hh'));
+        timeComponents.filter('[data-time-component=minutes]').text(date.format('mm'));
+        timeComponents.filter('[data-time-component=seconds]').text(date.format('ss'));
+
+        fillHours();
+        fillMinutes();
+        fillSeconds();
+      },
+
+      update = function() {
+        if (!widget) {
+          return;
+        }
+        fillDate();
+        fillTime();
+      },
+
+      setValue = function(targetMoment) {
+        var oldDate = unset ? null : date;
+
+        // case of calling setValue(null or false)
+        if (!targetMoment) {
+          unset = true;
+          input.val('');
+          element.data('date', '');
+          notifyEvent({
+            type: 'dp.change',
+            date: false,
+            oldDate: oldDate
+          });
+          update();
+          return;
+        }
+
+        targetMoment = targetMoment.clone().locale(options.locale);
+
+        if (hasTimeZone()) {
+          targetMoment.tz(options.timeZone);
+        }
+
+        if (options.stepping !== 1) {
+          targetMoment.minutes((Math.round(targetMoment.minutes() / options.stepping) * options.stepping)).seconds(0);
+
+          while (options.minDate && targetMoment.isBefore(options.minDate)) {
+            targetMoment.add(options.stepping, 'minutes');
+          }
+        }
+
+        if (isValid(targetMoment)) {
+          date = targetMoment;
+          viewDate = date.clone();
+          input.val(date.format(actualFormat));
+          element.data('date', date.format(actualFormat));
+          unset = false;
+          update();
+          notifyEvent({
+            type: 'dp.change',
+            date: date.clone(),
+            oldDate: oldDate
+          });
+        } else {
+          if (!options.keepInvalid) {
+            input.val(unset ? '' : date.format(actualFormat));
+          } else {
+            notifyEvent({
+              type: 'dp.change',
+              date: targetMoment,
+              oldDate: oldDate
+            });
+          }
+          notifyEvent({
+            type: 'dp.error',
+            date: targetMoment,
+            oldDate: oldDate
+          });
+        }
+      },
+
+      /**
+       * Hides the widget. Possibly will emit dp.hide
+       */
+      hide = function() {
+        var transitioning = false;
+        if (!widget) {
+          return picker;
+        }
+        // Ignore event if in the middle of a picker transition
+        widget.find('.collapse').each(function() {
+          var collapseData = $(this).data('collapse');
+          if (collapseData && collapseData.transitioning) {
+            transitioning = true;
+            return false;
+          }
+          return true;
+        });
+        if (transitioning) {
+          return picker;
+        }
+        if (component && component.hasClass('btn')) {
+          component.toggleClass('active');
+        }
+
+        $(window).off('resize', place);
+        widget.off('click', '[data-action]');
+        widget.off('mousedown', false);
+
+        // Creative Tim Changes - we remove the ".open" class, then, fter 400 ms call the .hide() method, in this way the animations will be the same with the other dropdowns from the dashboard
+
+        widget.removeClass('open');
+
+        setTimeout(function() {
+          widget.remove();
+          widget.hide();
+
+          widget = false;
+
+          notifyEvent({
+            type: 'dp.hide',
+            date: date.clone()
+          });
+
+          input.blur();
+
+          currentViewMode = 0;
+          viewDate = date.clone();
+
+          return picker;
+        }, 40);
+      },
+
+      clear = function() {
+        setValue(null);
+      },
+
+      parseInputDate = function(inputDate) {
+        if (options.parseInputDate === undefined) {
+          if (!moment.isMoment(inputDate) || inputDate instanceof Date) {
+            inputDate = getMoment(inputDate);
+          }
+        } else {
+          inputDate = options.parseInputDate(inputDate);
+        }
+        //inputDate.locale(options.locale);
+        return inputDate;
+      },
+
+      /********************************************************************************
+       *
+       * Widget UI interaction functions
+       *
+       ********************************************************************************/
+      actions = {
+        next: function() {
+          var navFnc = datePickerModes[currentViewMode].navFnc;
+          viewDate.add(datePickerModes[currentViewMode].navStep, navFnc);
+          fillDate();
+          viewUpdate(navFnc);
+        },
+
+        previous: function() {
+          var navFnc = datePickerModes[currentViewMode].navFnc;
+          viewDate.subtract(datePickerModes[currentViewMode].navStep, navFnc);
+          fillDate();
+          viewUpdate(navFnc);
+        },
+
+        pickerSwitch: function() {
+          showMode(1);
+        },
+
+        selectMonth: function(e) {
+          var month = $(e.target).closest('tbody').find('span').index($(e.target));
+          viewDate.month(month);
+          if (currentViewMode === minViewModeNumber) {
+            setValue(date.clone().year(viewDate.year()).month(viewDate.month()));
+            if (!options.inline) {
+              hide();
+            }
+          } else {
+            showMode(-1);
+            fillDate();
+          }
+          viewUpdate('M');
+        },
+
+        selectYear: function(e) {
+          var year = parseInt($(e.target).text(), 10) || 0;
+          viewDate.year(year);
+          if (currentViewMode === minViewModeNumber) {
+            setValue(date.clone().year(viewDate.year()));
+            if (!options.inline) {
+              hide();
+            }
+          } else {
+            showMode(-1);
+            fillDate();
+          }
+          viewUpdate('YYYY');
+        },
+
+        selectDecade: function(e) {
+          var year = parseInt($(e.target).data('selection'), 10) || 0;
+          viewDate.year(year);
+          if (currentViewMode === minViewModeNumber) {
+            setValue(date.clone().year(viewDate.year()));
+            if (!options.inline) {
+              hide();
+            }
+          } else {
+            showMode(-1);
+            fillDate();
+          }
+          viewUpdate('YYYY');
+        },
+
+        selectDay: function(e) {
+          var day = viewDate.clone();
+          if ($(e.target).is('.old')) {
+            day.subtract(1, 'M');
+          }
+          if ($(e.target).is('.new')) {
+            day.add(1, 'M');
+          }
+          setValue(day.date(parseInt($(e.target).text(), 10)));
+          if (!hasTime() && !options.keepOpen && !options.inline) {
+            hide();
+          }
+        },
+
+        incrementHours: function() {
+          var newDate = date.clone().add(1, 'h');
+          if (isValid(newDate, 'h')) {
+            setValue(newDate);
+          }
+        },
+
+        incrementMinutes: function() {
+          var newDate = date.clone().add(options.stepping, 'm');
+          if (isValid(newDate, 'm')) {
+            setValue(newDate);
+          }
+        },
+
+        incrementSeconds: function() {
+          var newDate = date.clone().add(1, 's');
+          if (isValid(newDate, 's')) {
+            setValue(newDate);
+          }
+        },
+
+        decrementHours: function() {
+          var newDate = date.clone().subtract(1, 'h');
+          if (isValid(newDate, 'h')) {
+            setValue(newDate);
+          }
+        },
+
+        decrementMinutes: function() {
+          var newDate = date.clone().subtract(options.stepping, 'm');
+          if (isValid(newDate, 'm')) {
+            setValue(newDate);
+          }
+        },
+
+        decrementSeconds: function() {
+          var newDate = date.clone().subtract(1, 's');
+          if (isValid(newDate, 's')) {
+            setValue(newDate);
+          }
+        },
+
+        togglePeriod: function() {
+          setValue(date.clone().add((date.hours() >= 12) ? -12 : 12, 'h'));
+        },
+
+        togglePicker: function(e) {
+          var $this = $(e.target),
+            $parent = $this.closest('ul'),
+            expanded = $parent.find('.show'),
+            closed = $parent.find('.collapse:not(.show)'),
+            collapseData;
+
+          if (expanded && expanded.length) {
+            collapseData = expanded.data('collapse');
+            if (collapseData && collapseData.transitioning) {
+              return;
+            }
+            if (expanded.collapse) { // if collapse plugin is available through bootstrap.js then use it
+              expanded.collapse('hide');
+              closed.collapse('show');
+            } else { // otherwise just toggle in class on the two views
+              expanded.removeClass('show');
+              closed.addClass('show');
+            }
+            if ($this.is('span')) {
+              $this.toggleClass(options.icons.time + ' ' + options.icons.date);
+            } else {
+              $this.find('span').toggleClass(options.icons.time + ' ' + options.icons.date);
+            }
+
+            // NOTE: uncomment if toggled state will be restored in show()
+            //if (component) {
+            //    component.find('span').toggleClass(options.icons.time + ' ' + options.icons.date);
+            //}
+          }
+        },
+
+        showPicker: function() {
+          widget.find('.timepicker > div:not(.timepicker-picker)').hide();
+          widget.find('.timepicker .timepicker-picker').show();
+        },
+
+        showHours: function() {
+          widget.find('.timepicker .timepicker-picker').hide();
+          widget.find('.timepicker .timepicker-hours').show();
+        },
+
+        showMinutes: function() {
+          widget.find('.timepicker .timepicker-picker').hide();
+          widget.find('.timepicker .timepicker-minutes').show();
+        },
+
+        showSeconds: function() {
+          widget.find('.timepicker .timepicker-picker').hide();
+          widget.find('.timepicker .timepicker-seconds').show();
+        },
+
+        selectHour: function(e) {
+          var hour = parseInt($(e.target).text(), 10);
+
+          if (!use24Hours) {
+            if (date.hours() >= 12) {
+              if (hour !== 12) {
+                hour += 12;
+              }
+            } else {
+              if (hour === 12) {
+                hour = 0;
+              }
+            }
+          }
+          setValue(date.clone().hours(hour));
+          actions.showPicker.call(picker);
+        },
+
+        selectMinute: function(e) {
+          setValue(date.clone().minutes(parseInt($(e.target).text(), 10)));
+          actions.showPicker.call(picker);
+        },
+
+        selectSecond: function(e) {
+          setValue(date.clone().seconds(parseInt($(e.target).text(), 10)));
+          actions.showPicker.call(picker);
+        },
+
+        clear: clear,
+
+        today: function() {
+          var todaysDate = getMoment();
+          if (isValid(todaysDate, 'd')) {
+            setValue(todaysDate);
+          }
+        },
+
+        close: hide
+      },
+
+      doAction = function(e) {
+        if ($(e.currentTarget).is('.disabled')) {
+          return false;
+        }
+        actions[$(e.currentTarget).data('action')].apply(picker, arguments);
+        return false;
+      },
+
+      /**
+       * Shows the widget. Possibly will emit dp.show and dp.change
+       */
+      show = function() {
+        var currentMoment,
+          useCurrentGranularity = {
+            'year': function(m) {
+              return m.month(0).date(1).hours(0).seconds(0).minutes(0);
+            },
+            'month': function(m) {
+              return m.date(1).hours(0).seconds(0).minutes(0);
+            },
+            'day': function(m) {
+              return m.hours(0).seconds(0).minutes(0);
+            },
+            'hour': function(m) {
+              return m.seconds(0).minutes(0);
+            },
+            'minute': function(m) {
+              return m.seconds(0);
+            }
+          };
+
+        if (input.prop('disabled') || (!options.ignoreReadonly && input.prop('readonly')) || widget) {
+          return picker;
+        }
+        if (input.val() !== undefined && input.val().trim().length !== 0) {
+          setValue(parseInputDate(input.val().trim()));
+        } else if (unset && options.useCurrent && (options.inline || (input.is('input') && input.val().trim().length === 0))) {
+          currentMoment = getMoment();
+          if (typeof options.useCurrent === 'string') {
+            currentMoment = useCurrentGranularity[options.useCurrent](currentMoment);
+          }
+          setValue(currentMoment);
+        }
+        widget = getTemplate();
+
+        fillDow();
+        fillMonths();
+
+        widget.find('.timepicker-hours').hide();
+        widget.find('.timepicker-minutes').hide();
+        widget.find('.timepicker-seconds').hide();
+
+        update();
+        showMode();
+
+        $(window).on('resize', place);
+        widget.on('click', '[data-action]', doAction); // this handles clicks on the widget
+        widget.on('mousedown', false);
+
+        if (component && component.hasClass('btn')) {
+          component.toggleClass('active');
+        }
+        place();
+        widget.show();
+        if (options.focusOnShow && !input.is(':focus')) {
+          input.focus();
+        }
+
+        notifyEvent({
+          type: 'dp.show'
+        });
+        return picker;
+      },
+
+      /**
+       * Shows or hides the widget
+       */
+      toggle = function() {
+        return (widget ? hide() : show());
+      },
+
+      keydown = function(e) {
+        var handler = null,
+          index,
+          index2,
+          pressedKeys = [],
+          pressedModifiers = {},
+          currentKey = e.which,
+          keyBindKeys,
+          allModifiersPressed,
+          pressed = 'p';
+
+        keyState[currentKey] = pressed;
+
+        for (index in keyState) {
+          if (keyState.hasOwnProperty(index) && keyState[index] === pressed) {
+            pressedKeys.push(index);
+            if (parseInt(index, 10) !== currentKey) {
+              pressedModifiers[index] = true;
+            }
+          }
+        }
+
+        for (index in options.keyBinds) {
+          if (options.keyBinds.hasOwnProperty(index) && typeof(options.keyBinds[index]) === 'function') {
+            keyBindKeys = index.split(' ');
+            if (keyBindKeys.length === pressedKeys.length && keyMap[currentKey] === keyBindKeys[keyBindKeys.length - 1]) {
+              allModifiersPressed = true;
+              for (index2 = keyBindKeys.length - 2; index2 >= 0; index2--) {
+                if (!(keyMap[keyBindKeys[index2]] in pressedModifiers)) {
+                  allModifiersPressed = false;
+                  break;
+                }
+              }
+              if (allModifiersPressed) {
+                handler = options.keyBinds[index];
+                break;
+              }
+            }
+          }
+        }
+
+        if (handler) {
+          handler.call(picker, widget);
+          e.stopPropagation();
+          e.preventDefault();
+        }
+      },
+
+      keyup = function(e) {
+        keyState[e.which] = 'r';
+        e.stopPropagation();
+        e.preventDefault();
+      },
+
+      change = function(e) {
+        var val = $(e.target).val().trim(),
+          parsedDate = val ? parseInputDate(val) : null;
+        setValue(parsedDate);
+        e.stopImmediatePropagation();
+        return false;
+      },
+
+      attachDatePickerElementEvents = function() {
+        input.on({
+          'change': change,
+          'blur': options.debug ? '' : hide,
+          'keydown': keydown,
+          'keyup': keyup,
+          'focus': options.allowInputToggle ? show : ''
+        });
+
+        if (element.is('input')) {
+          input.on({
+            'focus': show
+          });
+        } else if (component) {
+          component.on('click', toggle);
+          component.on('mousedown', false);
+        }
+      },
+
+      detachDatePickerElementEvents = function() {
+        input.off({
+          'change': change,
+          'blur': blur,
+          'keydown': keydown,
+          'keyup': keyup,
+          'focus': options.allowInputToggle ? hide : ''
+        });
+
+        if (element.is('input')) {
+          input.off({
+            'focus': show
+          });
+        } else if (component) {
+          component.off('click', toggle);
+          component.off('mousedown', false);
+        }
+      },
+
+      indexGivenDates = function(givenDatesArray) {
+        // Store given enabledDates and disabledDates as keys.
+        // This way we can check their existence in O(1) time instead of looping through whole array.
+        // (for example: options.enabledDates['2014-02-27'] === true)
+        var givenDatesIndexed = {};
+        $.each(givenDatesArray, function() {
+          var dDate = parseInputDate(this);
+          if (dDate.isValid()) {
+            givenDatesIndexed[dDate.format('YYYY-MM-DD')] = true;
+          }
+        });
+        return (Object.keys(givenDatesIndexed).length) ? givenDatesIndexed : false;
+      },
+
+      indexGivenHours = function(givenHoursArray) {
+        // Store given enabledHours and disabledHours as keys.
+        // This way we can check their existence in O(1) time instead of looping through whole array.
+        // (for example: options.enabledHours['2014-02-27'] === true)
+        var givenHoursIndexed = {};
+        $.each(givenHoursArray, function() {
+          givenHoursIndexed[this] = true;
+        });
+        return (Object.keys(givenHoursIndexed).length) ? givenHoursIndexed : false;
+      },
+
+      initFormatting = function() {
+        var format = options.format || 'L LT';
+
+        actualFormat = format.replace(/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g, function(formatInput) {
+          var newinput = date.localeData().longDateFormat(formatInput) || formatInput;
+          return newinput.replace(/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g, function(formatInput2) { //temp fix for #740
+            return date.localeData().longDateFormat(formatInput2) || formatInput2;
+          });
+        });
+
+
+        parseFormats = options.extraFormats ? options.extraFormats.slice() : [];
+        if (parseFormats.indexOf(format) < 0 && parseFormats.indexOf(actualFormat) < 0) {
+          parseFormats.push(actualFormat);
+        }
+
+        use24Hours = (actualFormat.toLowerCase().indexOf('a') < 1 && actualFormat.replace(/\[.*?\]/g, '').indexOf('h') < 1);
+
+        if (isEnabled('y')) {
+          minViewModeNumber = 2;
+        }
+        if (isEnabled('M')) {
+          minViewModeNumber = 1;
+        }
+        if (isEnabled('d')) {
+          minViewModeNumber = 0;
+        }
+
+        currentViewMode = Math.max(minViewModeNumber, currentViewMode);
+
+        if (!unset) {
+          setValue(date);
+        }
+      };
+
+    /********************************************************************************
+     *
+     * Public API functions
+     * =====================
+     *
+     * Important: Do not expose direct references to private objects or the options
+     * object to the outer world. Always return a clone when returning values or make
+     * a clone when setting a private variable.
+     *
+     ********************************************************************************/
+    picker.destroy = function() {
+      ///<summary>Destroys the widget and removes all attached event listeners</summary>
+      hide();
+      detachDatePickerElementEvents();
+      element.removeData('DateTimePicker');
+      element.removeData('date');
+    };
+
+    picker.toggle = toggle;
+
+    picker.show = show;
+
+    picker.hide = hide;
+
+    picker.disable = function() {
+      ///<summary>Disables the input element, the component is attached to, by adding a disabled="true" attribute to it.
+      ///If the widget was visible before that call it is hidden. Possibly emits dp.hide</summary>
+      hide();
+      if (component && component.hasClass('btn')) {
+        component.addClass('disabled');
+      }
+      input.prop('disabled', true);
+      return picker;
+    };
+
+    picker.enable = function() {
+      ///<summary>Enables the input element, the component is attached to, by removing disabled attribute from it.</summary>
+      if (component && component.hasClass('btn')) {
+        component.removeClass('disabled');
+      }
+      input.prop('disabled', false);
+      return picker;
+    };
+
+    picker.ignoreReadonly = function(ignoreReadonly) {
+      if (arguments.length === 0) {
+        return options.ignoreReadonly;
+      }
+      if (typeof ignoreReadonly !== 'boolean') {
+        throw new TypeError('ignoreReadonly () expects a boolean parameter');
+      }
+      options.ignoreReadonly = ignoreReadonly;
+      return picker;
+    };
+
+    picker.options = function(newOptions) {
+      if (arguments.length === 0) {
+        return $.extend(true, {}, options);
+      }
+
+      if (!(newOptions instanceof Object)) {
+        throw new TypeError('options() options parameter should be an object');
+      }
+      $.extend(true, options, newOptions);
+      $.each(options, function(key, value) {
+        if (picker[key] !== undefined) {
+          picker[key](value);
+        } else {
+          throw new TypeError('option ' + key + ' is not recognized!');
+        }
+      });
+      return picker;
+    };
+
+    picker.date = function(newDate) {
+      ///<signature helpKeyword="$.fn.datetimepicker.date">
+      ///<summary>Returns the component's model current date, a moment object or null if not set.</summary>
+      ///<returns type="Moment">date.clone()</returns>
+      ///</signature>
+      ///<signature>
+      ///<summary>Sets the components model current moment to it. Passing a null value unsets the components model current moment. Parsing of the newDate parameter is made using moment library with the options.format and options.useStrict components configuration.</summary>
+      ///<param name="newDate" locid="$.fn.datetimepicker.date_p:newDate">Takes string, Date, moment, null parameter.</param>
+      ///</signature>
+      if (arguments.length === 0) {
+        if (unset) {
+          return null;
+        }
+        return date.clone();
+      }
+
+      if (newDate !== null && typeof newDate !== 'string' && !moment.isMoment(newDate) && !(newDate instanceof Date)) {
+        throw new TypeError('date() parameter must be one of [null, string, moment or Date]');
+      }
+
+      setValue(newDate === null ? null : parseInputDate(newDate));
+      return picker;
+    };
+
+    picker.format = function(newFormat) {
+      ///<summary>test su</summary>
+      ///<param name="newFormat">info about para</param>
+      ///<returns type="string|boolean">returns foo</returns>
+      if (arguments.length === 0) {
+        return options.format;
+      }
+
+      if ((typeof newFormat !== 'string') && ((typeof newFormat !== 'boolean') || (newFormat !== false))) {
+        throw new TypeError('format() expects a string or boolean:false parameter ' + newFormat);
+      }
+
+      options.format = newFormat;
+      if (actualFormat) {
+        initFormatting(); // reinit formatting
+      }
+      return picker;
+    };
+
+    picker.timeZone = function(newZone) {
+      if (arguments.length === 0) {
+        return options.timeZone;
+      }
+
+      if (typeof newZone !== 'string') {
+        throw new TypeError('newZone() expects a string parameter');
+      }
+
+      options.timeZone = newZone;
+
+      return picker;
+    };
+
+    picker.dayViewHeaderFormat = function(newFormat) {
+      if (arguments.length === 0) {
+        return options.dayViewHeaderFormat;
+      }
+
+      if (typeof newFormat !== 'string') {
+        throw new TypeError('dayViewHeaderFormat() expects a string parameter');
+      }
+
+      options.dayViewHeaderFormat = newFormat;
+      return picker;
+    };
+
+    picker.extraFormats = function(formats) {
+      if (arguments.length === 0) {
+        return options.extraFormats;
+      }
+
+      if (formats !== false && !(formats instanceof Array)) {
+        throw new TypeError('extraFormats() expects an array or false parameter');
+      }
+
+      options.extraFormats = formats;
+      if (parseFormats) {
+        initFormatting(); // reinit formatting
+      }
+      return picker;
+    };
+
+    picker.disabledDates = function(dates) {
+      ///<signature helpKeyword="$.fn.datetimepicker.disabledDates">
+      ///<summary>Returns an array with the currently set disabled dates on the component.</summary>
+      ///<returns type="array">options.disabledDates</returns>
+      ///</signature>
+      ///<signature>
+      ///<summary>Setting this takes precedence over options.minDate, options.maxDate configuration. Also calling this function removes the configuration of
+      ///options.enabledDates if such exist.</summary>
+      ///<param name="dates" locid="$.fn.datetimepicker.disabledDates_p:dates">Takes an [ string or Date or moment ] of values and allows the user to select only from those days.</param>
+      ///</signature>
+      if (arguments.length === 0) {
+        return (options.disabledDates ? $.extend({}, options.disabledDates) : options.disabledDates);
+      }
+
+      if (!dates) {
+        options.disabledDates = false;
+        update();
+        return picker;
+      }
+      if (!(dates instanceof Array)) {
+        throw new TypeError('disabledDates() expects an array parameter');
+      }
+      options.disabledDates = indexGivenDates(dates);
+      options.enabledDates = false;
+      update();
+      return picker;
+    };
+
+    picker.enabledDates = function(dates) {
+      ///<signature helpKeyword="$.fn.datetimepicker.enabledDates">
+      ///<summary>Returns an array with the currently set enabled dates on the component.</summary>
+      ///<returns type="array">options.enabledDates</returns>
+      ///</signature>
+      ///<signature>
+      ///<summary>Setting this takes precedence over options.minDate, options.maxDate configuration. Also calling this function removes the configuration of options.disabledDates if such exist.</summary>
+      ///<param name="dates" locid="$.fn.datetimepicker.enabledDates_p:dates">Takes an [ string or Date or moment ] of values and allows the user to select only from those days.</param>
+      ///</signature>
+      if (arguments.length === 0) {
+        return (options.enabledDates ? $.extend({}, options.enabledDates) : options.enabledDates);
+      }
+
+      if (!dates) {
+        options.enabledDates = false;
+        update();
+        return picker;
+      }
+      if (!(dates instanceof Array)) {
+        throw new TypeError('enabledDates() expects an array parameter');
+      }
+      options.enabledDates = indexGivenDates(dates);
+      options.disabledDates = false;
+      update();
+      return picker;
+    };
+
+    picker.daysOfWeekDisabled = function(daysOfWeekDisabled) {
+      if (arguments.length === 0) {
+        return options.daysOfWeekDisabled.splice(0);
+      }
+
+      if ((typeof daysOfWeekDisabled === 'boolean') && !daysOfWeekDisabled) {
+        options.daysOfWeekDisabled = false;
+        update();
+        return picker;
+      }
+
+      if (!(daysOfWeekDisabled instanceof Array)) {
+        throw new TypeError('daysOfWeekDisabled() expects an array parameter');
+      }
+      options.daysOfWeekDisabled = daysOfWeekDisabled.reduce(function(previousValue, currentValue) {
+        currentValue = parseInt(currentValue, 10);
+        if (currentValue > 6 || currentValue < 0 || isNaN(currentValue)) {
+          return previousValue;
+        }
+        if (previousValue.indexOf(currentValue) === -1) {
+          previousValue.push(currentValue);
+        }
+        return previousValue;
+      }, []).sort();
+      if (options.useCurrent && !options.keepInvalid) {
+        var tries = 0;
+        while (!isValid(date, 'd')) {
+          date.add(1, 'd');
+          if (tries === 31) {
+            throw 'Tried 31 times to find a valid date';
+          }
+          tries++;
+        }
+        setValue(date);
+      }
+      update();
+      return picker;
+    };
+
+    picker.maxDate = function(maxDate) {
+      if (arguments.length === 0) {
+        return options.maxDate ? options.maxDate.clone() : options.maxDate;
+      }
+
+      if ((typeof maxDate === 'boolean') && maxDate === false) {
+        options.maxDate = false;
+        update();
+        return picker;
+      }
+
+      if (typeof maxDate === 'string') {
+        if (maxDate === 'now' || maxDate === 'moment') {
+          maxDate = getMoment();
+        }
+      }
+
+      var parsedDate = parseInputDate(maxDate);
+
+      if (!parsedDate.isValid()) {
+        throw new TypeError('maxDate() Could not parse date parameter: ' + maxDate);
+      }
+      if (options.minDate && parsedDate.isBefore(options.minDate)) {
+        throw new TypeError('maxDate() date parameter is before options.minDate: ' + parsedDate.format(actualFormat));
+      }
+      options.maxDate = parsedDate;
+      if (options.useCurrent && !options.keepInvalid && date.isAfter(maxDate)) {
+        setValue(options.maxDate);
+      }
+      if (viewDate.isAfter(parsedDate)) {
+        viewDate = parsedDate.clone().subtract(options.stepping, 'm');
+      }
+      update();
+      return picker;
+    };
+
+    picker.minDate = function(minDate) {
+      if (arguments.length === 0) {
+        return options.minDate ? options.minDate.clone() : options.minDate;
+      }
+
+      if ((typeof minDate === 'boolean') && minDate === false) {
+        options.minDate = false;
+        update();
+        return picker;
+      }
+
+      if (typeof minDate === 'string') {
+        if (minDate === 'now' || minDate === 'moment') {
+          minDate = getMoment();
+        }
+      }
+
+      var parsedDate = parseInputDate(minDate);
+
+      if (!parsedDate.isValid()) {
+        throw new TypeError('minDate() Could not parse date parameter: ' + minDate);
+      }
+      if (options.maxDate && parsedDate.isAfter(options.maxDate)) {
+        throw new TypeError('minDate() date parameter is after options.maxDate: ' + parsedDate.format(actualFormat));
+      }
+      options.minDate = parsedDate;
+      if (options.useCurrent && !options.keepInvalid && date.isBefore(minDate)) {
+        setValue(options.minDate);
+      }
+      if (viewDate.isBefore(parsedDate)) {
+        viewDate = parsedDate.clone().add(options.stepping, 'm');
+      }
+      update();
+      return picker;
+    };
+
+    picker.defaultDate = function(defaultDate) {
+      ///<signature helpKeyword="$.fn.datetimepicker.defaultDate">
+      ///<summary>Returns a moment with the options.defaultDate option configuration or false if not set</summary>
+      ///<returns type="Moment">date.clone()</returns>
+      ///</signature>
+      ///<signature>
+      ///<summary>Will set the picker's inital date. If a boolean:false value is passed the options.defaultDate parameter is cleared.</summary>
+      ///<param name="defaultDate" locid="$.fn.datetimepicker.defaultDate_p:defaultDate">Takes a string, Date, moment, boolean:false</param>
+      ///</signature>
+      if (arguments.length === 0) {
+        return options.defaultDate ? options.defaultDate.clone() : options.defaultDate;
+      }
+      if (!defaultDate) {
+        options.defaultDate = false;
+        return picker;
+      }
+
+      if (typeof defaultDate === 'string') {
+        if (defaultDate === 'now' || defaultDate === 'moment') {
+          defaultDate = getMoment();
+        } else {
+          defaultDate = getMoment(defaultDate);
+        }
+      }
+
+      var parsedDate = parseInputDate(defaultDate);
+      if (!parsedDate.isValid()) {
+        throw new TypeError('defaultDate() Could not parse date parameter: ' + defaultDate);
+      }
+      if (!isValid(parsedDate)) {
+        throw new TypeError('defaultDate() date passed is invalid according to component setup validations');
+      }
+
+      options.defaultDate = parsedDate;
+
+      if ((options.defaultDate && options.inline) || input.val().trim() === '') {
+        setValue(options.defaultDate);
+      }
+      return picker;
+    };
+
+    picker.locale = function(locale) {
+      if (arguments.length === 0) {
+        return options.locale;
+      }
+
+      if (!moment.localeData(locale)) {
+        throw new TypeError('locale() locale ' + locale + ' is not loaded from moment locales!');
+      }
+
+      options.locale = locale;
+      date.locale(options.locale);
+      viewDate.locale(options.locale);
+
+      if (actualFormat) {
+        initFormatting(); // reinit formatting
+      }
+      if (widget) {
+        hide();
+        show();
+      }
+      return picker;
+    };
+
+    picker.stepping = function(stepping) {
+      if (arguments.length === 0) {
+        return options.stepping;
+      }
+
+      stepping = parseInt(stepping, 10);
+      if (isNaN(stepping) || stepping < 1) {
+        stepping = 1;
+      }
+      options.stepping = stepping;
+      return picker;
+    };
+
+    picker.useCurrent = function(useCurrent) {
+      var useCurrentOptions = ['year', 'month', 'day', 'hour', 'minute'];
+      if (arguments.length === 0) {
+        return options.useCurrent;
+      }
+
+      if ((typeof useCurrent !== 'boolean') && (typeof useCurrent !== 'string')) {
+        throw new TypeError('useCurrent() expects a boolean or string parameter');
+      }
+      if (typeof useCurrent === 'string' && useCurrentOptions.indexOf(useCurrent.toLowerCase()) === -1) {
+        throw new TypeError('useCurrent() expects a string parameter of ' + useCurrentOptions.join(', '));
+      }
+      options.useCurrent = useCurrent;
+      return picker;
+    };
+
+    picker.collapse = function(collapse) {
+      if (arguments.length === 0) {
+        return options.collapse;
+      }
+
+      if (typeof collapse !== 'boolean') {
+        throw new TypeError('collapse() expects a boolean parameter');
+      }
+      if (options.collapse === collapse) {
+        return picker;
+      }
+      options.collapse = collapse;
+      if (widget) {
+        hide();
+        show();
+      }
+      return picker;
+    };
+
+    picker.icons = function(icons) {
+      if (arguments.length === 0) {
+        return $.extend({}, options.icons);
+      }
+
+      if (!(icons instanceof Object)) {
+        throw new TypeError('icons() expects parameter to be an Object');
+      }
+      $.extend(options.icons, icons);
+      if (widget) {
+        hide();
+        show();
+      }
+      return picker;
+    };
+
+    picker.tooltips = function(tooltips) {
+      if (arguments.length === 0) {
+        return $.extend({}, options.tooltips);
+      }
+
+      if (!(tooltips instanceof Object)) {
+        throw new TypeError('tooltips() expects parameter to be an Object');
+      }
+      $.extend(options.tooltips, tooltips);
+      if (widget) {
+        hide();
+        show();
+      }
+      return picker;
+    };
+
+    picker.useStrict = function(useStrict) {
+      if (arguments.length === 0) {
+        return options.useStrict;
+      }
+
+      if (typeof useStrict !== 'boolean') {
+        throw new TypeError('useStrict() expects a boolean parameter');
+      }
+      options.useStrict = useStrict;
+      return picker;
+    };
+
+    picker.sideBySide = function(sideBySide) {
+      if (arguments.length === 0) {
+        return options.sideBySide;
+      }
+
+      if (typeof sideBySide !== 'boolean') {
+        throw new TypeError('sideBySide() expects a boolean parameter');
+      }
+      options.sideBySide = sideBySide;
+      if (widget) {
+        hide();
+        show();
+      }
+      return picker;
+    };
+
+    picker.viewMode = function(viewMode) {
+      if (arguments.length === 0) {
+        return options.viewMode;
+      }
+
+      if (typeof viewMode !== 'string') {
+        throw new TypeError('viewMode() expects a string parameter');
+      }
+
+      if (viewModes.indexOf(viewMode) === -1) {
+        throw new TypeError('viewMode() parameter must be one of (' + viewModes.join(', ') + ') value');
+      }
+
+      options.viewMode = viewMode;
+      currentViewMode = Math.max(viewModes.indexOf(viewMode), minViewModeNumber);
+
+      showMode();
+      return picker;
+    };
+
+    picker.toolbarPlacement = function(toolbarPlacement) {
+      if (arguments.length === 0) {
+        return options.toolbarPlacement;
+      }
+
+      if (typeof toolbarPlacement !== 'string') {
+        throw new TypeError('toolbarPlacement() expects a string parameter');
+      }
+      if (toolbarPlacements.indexOf(toolbarPlacement) === -1) {
+        throw new TypeError('toolbarPlacement() parameter must be one of (' + toolbarPlacements.join(', ') + ') value');
+      }
+      options.toolbarPlacement = toolbarPlacement;
+
+      if (widget) {
+        hide();
+        show();
+      }
+      return picker;
+    };
+
+    picker.widgetPositioning = function(widgetPositioning) {
+      if (arguments.length === 0) {
+        return $.extend({}, options.widgetPositioning);
+      }
+
+      if (({}).toString.call(widgetPositioning) !== '[object Object]') {
+        throw new TypeError('widgetPositioning() expects an object variable');
+      }
+      if (widgetPositioning.horizontal) {
+        if (typeof widgetPositioning.horizontal !== 'string') {
+          throw new TypeError('widgetPositioning() horizontal variable must be a string');
+        }
+        widgetPositioning.horizontal = widgetPositioning.horizontal.toLowerCase();
+        if (horizontalModes.indexOf(widgetPositioning.horizontal) === -1) {
+          throw new TypeError('widgetPositioning() expects horizontal parameter to be one of (' + horizontalModes.join(', ') + ')');
+        }
+        options.widgetPositioning.horizontal = widgetPositioning.horizontal;
+      }
+      if (widgetPositioning.vertical) {
+        if (typeof widgetPositioning.vertical !== 'string') {
+          throw new TypeError('widgetPositioning() vertical variable must be a string');
+        }
+        widgetPositioning.vertical = widgetPositioning.vertical.toLowerCase();
+        if (verticalModes.indexOf(widgetPositioning.vertical) === -1) {
+          throw new TypeError('widgetPositioning() expects vertical parameter to be one of (' + verticalModes.join(', ') + ')');
+        }
+        options.widgetPositioning.vertical = widgetPositioning.vertical;
+      }
+      update();
+      return picker;
+    };
+
+    picker.calendarWeeks = function(calendarWeeks) {
+      if (arguments.length === 0) {
+        return options.calendarWeeks;
+      }
+
+      if (typeof calendarWeeks !== 'boolean') {
+        throw new TypeError('calendarWeeks() expects parameter to be a boolean value');
+      }
+
+      options.calendarWeeks = calendarWeeks;
+      update();
+      return picker;
+    };
+
+    picker.showTodayButton = function(showTodayButton) {
+      if (arguments.length === 0) {
+        return options.showTodayButton;
+      }
+
+      if (typeof showTodayButton !== 'boolean') {
+        throw new TypeError('showTodayButton() expects a boolean parameter');
+      }
+
+      options.showTodayButton = showTodayButton;
+      if (widget) {
+        hide();
+        show();
+      }
+      return picker;
+    };
+
+    picker.showClear = function(showClear) {
+      if (arguments.length === 0) {
+        return options.showClear;
+      }
+
+      if (typeof showClear !== 'boolean') {
+        throw new TypeError('showClear() expects a boolean parameter');
+      }
+
+      options.showClear = showClear;
+      if (widget) {
+        hide();
+        show();
+      }
+      return picker;
+    };
+
+    picker.widgetParent = function(widgetParent) {
+      if (arguments.length === 0) {
+        return options.widgetParent;
+      }
+
+      if (typeof widgetParent === 'string') {
+        widgetParent = $(widgetParent);
+      }
+
+      if (widgetParent !== null && (typeof widgetParent !== 'string' && !(widgetParent instanceof $))) {
+        throw new TypeError('widgetParent() expects a string or a jQuery object parameter');
+      }
+
+      options.widgetParent = widgetParent;
+      if (widget) {
+        hide();
+        show();
+      }
+      return picker;
+    };
+
+    picker.keepOpen = function(keepOpen) {
+      if (arguments.length === 0) {
+        return options.keepOpen;
+      }
+
+      if (typeof keepOpen !== 'boolean') {
+        throw new TypeError('keepOpen() expects a boolean parameter');
+      }
+
+      options.keepOpen = keepOpen;
+      return picker;
+    };
+
+    picker.focusOnShow = function(focusOnShow) {
+      if (arguments.length === 0) {
+        return options.focusOnShow;
+      }
+
+      if (typeof focusOnShow !== 'boolean') {
+        throw new TypeError('focusOnShow() expects a boolean parameter');
+      }
+
+      options.focusOnShow = focusOnShow;
+      return picker;
+    };
+
+    picker.inline = function(inline) {
+      if (arguments.length === 0) {
+        return options.inline;
+      }
+
+      if (typeof inline !== 'boolean') {
+        throw new TypeError('inline() expects a boolean parameter');
+      }
+
+      options.inline = inline;
+      return picker;
+    };
+
+    picker.clear = function() {
+      clear();
+      return picker;
+    };
+
+    picker.keyBinds = function(keyBinds) {
+      if (arguments.length === 0) {
+        return options.keyBinds;
+      }
+
+      options.keyBinds = keyBinds;
+      return picker;
+    };
+
+    picker.getMoment = function(d) {
+      return getMoment(d);
+    };
+
+    picker.debug = function(debug) {
+      if (typeof debug !== 'boolean') {
+        throw new TypeError('debug() expects a boolean parameter');
+      }
+
+      options.debug = debug;
+      return picker;
+    };
+
+    picker.allowInputToggle = function(allowInputToggle) {
+      if (arguments.length === 0) {
+        return options.allowInputToggle;
+      }
+
+      if (typeof allowInputToggle !== 'boolean') {
+        throw new TypeError('allowInputToggle() expects a boolean parameter');
+      }
+
+      options.allowInputToggle = allowInputToggle;
+      return picker;
+    };
+
+    picker.showClose = function(showClose) {
+      if (arguments.length === 0) {
+        return options.showClose;
+      }
+
+      if (typeof showClose !== 'boolean') {
+        throw new TypeError('showClose() expects a boolean parameter');
+      }
+
+      options.showClose = showClose;
+      return picker;
+    };
+
+    picker.keepInvalid = function(keepInvalid) {
+      if (arguments.length === 0) {
+        return options.keepInvalid;
+      }
+
+      if (typeof keepInvalid !== 'boolean') {
+        throw new TypeError('keepInvalid() expects a boolean parameter');
+      }
+      options.keepInvalid = keepInvalid;
+      return picker;
+    };
+
+    picker.datepickerInput = function(datepickerInput) {
+      if (arguments.length === 0) {
+        return options.datepickerInput;
+      }
+
+      if (typeof datepickerInput !== 'string') {
+        throw new TypeError('datepickerInput() expects a string parameter');
+      }
+
+      options.datepickerInput = datepickerInput;
+      return picker;
+    };
+
+    picker.parseInputDate = function(parseInputDate) {
+      if (arguments.length === 0) {
+        return options.parseInputDate;
+      }
+
+      if (typeof parseInputDate !== 'function') {
+        throw new TypeError('parseInputDate() sholud be as function');
+      }
+
+      options.parseInputDate = parseInputDate;
+
+      return picker;
+    };
+
+    picker.disabledTimeIntervals = function(disabledTimeIntervals) {
+      ///<signature helpKeyword="$.fn.datetimepicker.disabledTimeIntervals">
+      ///<summary>Returns an array with the currently set disabled dates on the component.</summary>
+      ///<returns type="array">options.disabledTimeIntervals</returns>
+      ///</signature>
+      ///<signature>
+      ///<summary>Setting this takes precedence over options.minDate, options.maxDate configuration. Also calling this function removes the configuration of
+      ///options.enabledDates if such exist.</summary>
+      ///<param name="dates" locid="$.fn.datetimepicker.disabledTimeIntervals_p:dates">Takes an [ string or Date or moment ] of values and allows the user to select only from those days.</param>
+      ///</signature>
+      if (arguments.length === 0) {
+        return (options.disabledTimeIntervals ? $.extend({}, options.disabledTimeIntervals) : options.disabledTimeIntervals);
+      }
+
+      if (!disabledTimeIntervals) {
+        options.disabledTimeIntervals = false;
+        update();
+        return picker;
+      }
+      if (!(disabledTimeIntervals instanceof Array)) {
+        throw new TypeError('disabledTimeIntervals() expects an array parameter');
+      }
+      options.disabledTimeIntervals = disabledTimeIntervals;
+      update();
+      return picker;
+    };
+
+    picker.disabledHours = function(hours) {
+      ///<signature helpKeyword="$.fn.datetimepicker.disabledHours">
+      ///<summary>Returns an array with the currently set disabled hours on the component.</summary>
+      ///<returns type="array">options.disabledHours</returns>
+      ///</signature>
+      ///<signature>
+      ///<summary>Setting this takes precedence over options.minDate, options.maxDate configuration. Also calling this function removes the configuration of
+      ///options.enabledHours if such exist.</summary>
+      ///<param name="hours" locid="$.fn.datetimepicker.disabledHours_p:hours">Takes an [ int ] of values and disallows the user to select only from those hours.</param>
+      ///</signature>
+      if (arguments.length === 0) {
+        return (options.disabledHours ? $.extend({}, options.disabledHours) : options.disabledHours);
+      }
+
+      if (!hours) {
+        options.disabledHours = false;
+        update();
+        return picker;
+      }
+      if (!(hours instanceof Array)) {
+        throw new TypeError('disabledHours() expects an array parameter');
+      }
+      options.disabledHours = indexGivenHours(hours);
+      options.enabledHours = false;
+      if (options.useCurrent && !options.keepInvalid) {
+        var tries = 0;
+        while (!isValid(date, 'h')) {
+          date.add(1, 'h');
+          if (tries === 24) {
+            throw 'Tried 24 times to find a valid date';
+          }
+          tries++;
+        }
+        setValue(date);
+      }
+      update();
+      return picker;
+    };
+
+    picker.enabledHours = function(hours) {
+      ///<signature helpKeyword="$.fn.datetimepicker.enabledHours">
+      ///<summary>Returns an array with the currently set enabled hours on the component.</summary>
+      ///<returns type="array">options.enabledHours</returns>
+      ///</signature>
+      ///<signature>
+      ///<summary>Setting this takes precedence over options.minDate, options.maxDate configuration. Also calling this function removes the configuration of options.disabledHours if such exist.</summary>
+      ///<param name="hours" locid="$.fn.datetimepicker.enabledHours_p:hours">Takes an [ int ] of values and allows the user to select only from those hours.</param>
+      ///</signature>
+      if (arguments.length === 0) {
+        return (options.enabledHours ? $.extend({}, options.enabledHours) : options.enabledHours);
+      }
+
+      if (!hours) {
+        options.enabledHours = false;
+        update();
+        return picker;
+      }
+      if (!(hours instanceof Array)) {
+        throw new TypeError('enabledHours() expects an array parameter');
+      }
+      options.enabledHours = indexGivenHours(hours);
+      options.disabledHours = false;
+      if (options.useCurrent && !options.keepInvalid) {
+        var tries = 0;
+        while (!isValid(date, 'h')) {
+          date.add(1, 'h');
+          if (tries === 24) {
+            throw 'Tried 24 times to find a valid date';
+          }
+          tries++;
+        }
+        setValue(date);
+      }
+      update();
+      return picker;
+    };
+    /**
+     * Returns the component's model current viewDate, a moment object or null if not set. Passing a null value unsets the components model current moment. Parsing of the newDate parameter is made using moment library with the options.format and options.useStrict components configuration.
+     * @param {Takes string, viewDate, moment, null parameter.} newDate
+     * @returns {viewDate.clone()}
+     */
+    picker.viewDate = function(newDate) {
+      if (arguments.length === 0) {
+        return viewDate.clone();
+      }
+
+      if (!newDate) {
+        viewDate = date.clone();
+        return picker;
+      }
+
+      if (typeof newDate !== 'string' && !moment.isMoment(newDate) && !(newDate instanceof Date)) {
+        throw new TypeError('viewDate() parameter must be one of [string, moment or Date]');
+      }
+
+      viewDate = parseInputDate(newDate);
+      viewUpdate();
+      return picker;
+    };
+
+    // initializing element and component attributes
+    if (element.is('input')) {
+      input = element;
+    } else {
+      input = element.find(options.datepickerInput);
+      if (input.length === 0) {
+        input = element.find('input');
+      } else if (!input.is('input')) {
+        throw new Error('CSS class "' + options.datepickerInput + '" cannot be applied to non input element');
+      }
+    }
+
+    if (element.hasClass('input-group')) {
+      // in case there is more then one 'input-group-addon' Issue #48
+      if (element.find('.datepickerbutton').length === 0) {
+        component = element.find('.form-control');
+      } else {
+        component = element.find('.datepickerbutton');
+      }
+    }
+
+    if (!options.inline && !input.is('input')) {
+      throw new Error('Could not initialize DateTimePicker without an input element');
+    }
+
+    // Set defaults for date here now instead of in var declaration
+    date = getMoment();
+    viewDate = date.clone();
+
+    $.extend(true, options, dataToOptions());
+
+    picker.options(options);
+
+    initFormatting();
+
+    attachDatePickerElementEvents();
+
+    if (input.prop('disabled')) {
+      picker.disable();
+    }
+    if (input.is('input') && input.val().trim().length !== 0) {
+      setValue(parseInputDate(input.val().trim()));
+    } else if (options.defaultDate && input.attr('placeholder') === undefined) {
+      setValue(options.defaultDate);
+    }
+    if (options.inline) {
+      show();
+    }
+    return picker;
+  };
+
+  /********************************************************************************
+   *
+   * jQuery plugin constructor and defaults object
+   *
+   ********************************************************************************/
+
+  /**
+   * See (http://jquery.com/).
+   * @name jQuery
+   * @class
+   * See the jQuery Library  (http://jquery.com/) for full details.  This just
+   * documents the function and classes that are added to jQuery by this plug-in.
+   */
+  /**
+   * See (http://jquery.com/)
+   * @name fn
+   * @class
+   * See the jQuery Library  (http://jquery.com/) for full details.  This just
+   * documents the function and classes that are added to jQuery by this plug-in.
+   * @memberOf jQuery
+   */
+  /**
+   * Show comments
+   * @class datetimepicker
+   * @memberOf jQuery.fn
+   */
+  $.fn.datetimepicker = function(options) {
+    options = options || {};
+
+    var args = Array.prototype.slice.call(arguments, 1),
+      isInstance = true,
+      thisMethods = ['destroy', 'hide', 'show', 'toggle'],
+      returnValue;
+
+    if (typeof options === 'object') {
+      return this.each(function() {
+        var $this = $(this),
+          _options;
+        if (!$this.data('DateTimePicker')) {
+          // create a private copy of the defaults object
+          _options = $.extend(true, {}, $.fn.datetimepicker.defaults, options);
+          $this.data('DateTimePicker', dateTimePicker($this, _options));
+        }
+      });
+    } else if (typeof options === 'string') {
+      this.each(function() {
+        var $this = $(this),
+          instance = $this.data('DateTimePicker');
+        if (!instance) {
+          throw new Error('bootstrap-datetimepicker("' + options + '") method was called on an element that is not using DateTimePicker');
+        }
+
+        returnValue = instance[options].apply(instance, args);
+        isInstance = returnValue === instance;
+      });
+
+      if (isInstance || $.inArray(options, thisMethods) > -1) {
+        return this;
+      }
+
+      return returnValue;
+    }
+
+    throw new TypeError('Invalid arguments for DateTimePicker: ' + options);
+  };
+
+  $.fn.datetimepicker.defaults = {
+    timeZone: '',
+    format: false,
+    dayViewHeaderFormat: 'MMMM YYYY',
+    extraFormats: false,
+    stepping: 1,
+    minDate: false,
+    maxDate: false,
+    useCurrent: true,
+    collapse: true,
+    locale: moment.locale(),
+    defaultDate: false,
+    disabledDates: false,
+    enabledDates: false,
+    icons: {
+      time: 'glyphicon glyphicon-time',
+      date: 'glyphicon glyphicon-calendar',
+      up: 'glyphicon glyphicon-chevron-up',
+      down: 'glyphicon glyphicon-chevron-down',
+      previous: 'glyphicon glyphicon-chevron-left',
+      next: 'glyphicon glyphicon-chevron-right',
+      today: 'glyphicon glyphicon-screenshot',
+      clear: 'glyphicon glyphicon-trash',
+      close: 'glyphicon glyphicon-remove'
+    },
+    tooltips: {
+      today: 'Go to today',
+      clear: 'Clear selection',
+      close: 'Close the picker',
+      selectMonth: 'Select Month',
+      prevMonth: 'Previous Month',
+      nextMonth: 'Next Month',
+      selectYear: 'Select Year',
+      prevYear: 'Previous Year',
+      nextYear: 'Next Year',
+      selectDecade: 'Select Decade',
+      prevDecade: 'Previous Decade',
+      nextDecade: 'Next Decade',
+      prevCentury: 'Previous Century',
+      nextCentury: 'Next Century',
+      pickHour: 'Pick Hour',
+      incrementHour: 'Increment Hour',
+      decrementHour: 'Decrement Hour',
+      pickMinute: 'Pick Minute',
+      incrementMinute: 'Increment Minute',
+      decrementMinute: 'Decrement Minute',
+      pickSecond: 'Pick Second',
+      incrementSecond: 'Increment Second',
+      decrementSecond: 'Decrement Second',
+      togglePeriod: 'Toggle Period',
+      selectTime: 'Select Time'
+    },
+    useStrict: false,
+    sideBySide: false,
+    daysOfWeekDisabled: false,
+    calendarWeeks: false,
+    viewMode: 'days',
+    toolbarPlacement: 'default',
+    showTodayButton: false,
+    showClear: false,
+    showClose: false,
+    widgetPositioning: {
+      horizontal: 'auto',
+      vertical: 'auto'
+    },
+    widgetParent: null,
+    ignoreReadonly: false,
+    keepOpen: false,
+    focusOnShow: true,
+    inline: false,
+    keepInvalid: false,
+    datepickerInput: '.datepickerinput',
+    keyBinds: {
+      up: function(widget) {
+        if (!widget) {
+          return;
+        }
+        var d = this.date() || this.getMoment();
+        if (widget.find('.datepicker').is(':visible')) {
+          this.date(d.clone().subtract(7, 'd'));
+        } else {
+          this.date(d.clone().add(this.stepping(), 'm'));
+        }
+      },
+      down: function(widget) {
+        if (!widget) {
+          this.show();
+          return;
+        }
+        var d = this.date() || this.getMoment();
+        if (widget.find('.datepicker').is(':visible')) {
+          this.date(d.clone().add(7, 'd'));
+        } else {
+          this.date(d.clone().subtract(this.stepping(), 'm'));
+        }
+      },
+      'control up': function(widget) {
+        if (!widget) {
+          return;
+        }
+        var d = this.date() || this.getMoment();
+        if (widget.find('.datepicker').is(':visible')) {
+          this.date(d.clone().subtract(1, 'y'));
+        } else {
+          this.date(d.clone().add(1, 'h'));
+        }
+      },
+      'control down': function(widget) {
+        if (!widget) {
+          return;
+        }
+        var d = this.date() || this.getMoment();
+        if (widget.find('.datepicker').is(':visible')) {
+          this.date(d.clone().add(1, 'y'));
+        } else {
+          this.date(d.clone().subtract(1, 'h'));
+        }
+      },
+      left: function(widget) {
+        if (!widget) {
+          return;
+        }
+        var d = this.date() || this.getMoment();
+        if (widget.find('.datepicker').is(':visible')) {
+          this.date(d.clone().subtract(1, 'd'));
+        }
+      },
+      right: function(widget) {
+        if (!widget) {
+          return;
+        }
+        var d = this.date() || this.getMoment();
+        if (widget.find('.datepicker').is(':visible')) {
+          this.date(d.clone().add(1, 'd'));
+        }
+      },
+      pageUp: function(widget) {
+        if (!widget) {
+          return;
+        }
+        var d = this.date() || this.getMoment();
+        if (widget.find('.datepicker').is(':visible')) {
+          this.date(d.clone().subtract(1, 'M'));
+        }
+      },
+      pageDown: function(widget) {
+        if (!widget) {
+          return;
+        }
+        var d = this.date() || this.getMoment();
+        if (widget.find('.datepicker').is(':visible')) {
+          this.date(d.clone().add(1, 'M'));
+        }
+      },
+      enter: function() {
+        this.hide();
+      },
+      escape: function() {
+        this.hide();
+      },
+      //tab: function (widget) { //this break the flow of the form. disabling for now
+      //    var toggle = widget.find('.picker-switch a[data-action="togglePicker"]');
+      //    if(toggle.length > 0) toggle.click();
+      //},
+      'control space': function(widget) {
+        if (!widget) {
+          return;
+        }
+        if (widget.find('.timepicker').is(':visible')) {
+          widget.find('.btn[data-action="togglePeriod"]').click();
+        }
+      },
+      t: function() {
+        this.date(this.getMoment());
+      },
+      'delete': function() {
+        this.clear();
+      }
+    },
+    debug: false,
+    allowInputToggle: false,
+    disabledTimeIntervals: false,
+    disabledHours: false,
+    enabledHours: false,
+    viewDate: false
+  };
+
+  return $.fn.datetimepicker;
+}));

+ 786 - 0
src/main/resources/static/js/plugins/bootstrap-switch.js

@@ -0,0 +1,786 @@
+/**
+ * bootstrap-switch - Turn checkboxes and radio buttons into toggle switches.
+ *
+ * @version v3.3.4
+ * @homepage https://bttstrp.github.io/bootstrap-switch
+ * @author Mattia Larentis <mattia@larentis.eu> (http://larentis.eu)
+ * @license Apache-2.0
+ */
+
+(function(global, factory) {
+  if (typeof define === "function" && define.amd) {
+    define(['jquery'], factory);
+  } else if (typeof exports !== "undefined") {
+    factory(require('jquery'));
+  } else {
+    var mod = {
+      exports: {}
+    };
+    factory(global.jquery);
+    global.bootstrapSwitch = mod.exports;
+  }
+})(this, function(_jquery) {
+  'use strict';
+
+  var _jquery2 = _interopRequireDefault(_jquery);
+
+  function _interopRequireDefault(obj) {
+    return obj && obj.__esModule ? obj : {
+      default: obj
+    };
+  }
+
+  var _extends = Object.assign || function(target) {
+    for (var i = 1; i < arguments.length; i++) {
+      var source = arguments[i];
+
+      for (var key in source) {
+        if (Object.prototype.hasOwnProperty.call(source, key)) {
+          target[key] = source[key];
+        }
+      }
+    }
+
+    return target;
+  };
+
+  function _classCallCheck(instance, Constructor) {
+    if (!(instance instanceof Constructor)) {
+      throw new TypeError("Cannot call a class as a function");
+    }
+  }
+
+  var _createClass = function() {
+    function defineProperties(target, props) {
+      for (var i = 0; i < props.length; i++) {
+        var descriptor = props[i];
+        descriptor.enumerable = descriptor.enumerable || false;
+        descriptor.configurable = true;
+        if ("value" in descriptor) descriptor.writable = true;
+        Object.defineProperty(target, descriptor.key, descriptor);
+      }
+    }
+
+    return function(Constructor, protoProps, staticProps) {
+      if (protoProps) defineProperties(Constructor.prototype, protoProps);
+      if (staticProps) defineProperties(Constructor, staticProps);
+      return Constructor;
+    };
+  }();
+
+  var $ = _jquery2.default || window.jQuery || window.$;
+
+  var BootstrapSwitch = function() {
+    function BootstrapSwitch(element) {
+      var _this = this;
+
+      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+
+      _classCallCheck(this, BootstrapSwitch);
+
+      this.$element = $(element);
+      this.options = $.extend({}, $.fn.bootstrapSwitch.defaults, this._getElementOptions(), options);
+      this.prevOptions = {};
+      this.$wrapper = $('<div>', {
+        class: function _class() {
+          var classes = [];
+          classes.push(_this.options.state ? 'on' : 'off');
+          if (_this.options.size) {
+            classes.push(_this.options.size);
+          }
+          if (_this.options.disabled) {
+            classes.push('disabled');
+          }
+          if (_this.options.readonly) {
+            classes.push('readonly');
+          }
+          if (_this.options.indeterminate) {
+            classes.push('indeterminate');
+          }
+          if (_this.options.inverse) {
+            classes.push('inverse');
+          }
+          if (_this.$element.attr('id')) {
+            classes.push('id-' + _this.$element.attr('id'));
+          }
+          return classes.map(_this._getClass.bind(_this)).concat([_this.options.baseClass], _this._getClasses(_this.options.wrapperClass)).join(' ');
+        }
+      });
+      this.$container = $('<div>', {
+        class: this._getClass('container')
+      });
+      this.$on = $('<span>', {
+        html: this.options.onText,
+        class: this._getClass('handle-on') + ' ' + this._getClass(this.options.onColor)
+      });
+      this.$off = $('<span>', {
+        html: this.options.offText,
+        class: this._getClass('handle-off') + ' ' + this._getClass(this.options.offColor)
+      });
+      this.$label = $('<span>', {
+        html: this.options.labelText,
+        class: this._getClass('label')
+      });
+
+      this.$element.on('init.bootstrapSwitch', this.options.onInit.bind(this, element));
+      this.$element.on('switchChange.bootstrapSwitch', function() {
+        for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+          args[_key] = arguments[_key];
+        }
+
+        if (_this.options.onSwitchChange.apply(element, args) === false) {
+          if (_this.$element.is(':radio')) {
+            $('[name="' + _this.$element.attr('name') + '"]').trigger('previousState.bootstrapSwitch', true);
+          } else {
+            _this.$element.trigger('previousState.bootstrapSwitch', true);
+          }
+        }
+      });
+
+      this.$container = this.$element.wrap(this.$container).parent();
+      this.$wrapper = this.$container.wrap(this.$wrapper).parent();
+      this.$element.before(this.options.inverse ? this.$off : this.$on).before(this.$label).before(this.options.inverse ? this.$on : this.$off);
+
+      if (this.options.indeterminate) {
+        this.$element.prop('indeterminate', true);
+      }
+
+      this._init();
+      this._elementHandlers();
+      this._handleHandlers();
+      this._labelHandlers();
+      this._formHandler();
+      this._externalLabelHandler();
+      this.$element.trigger('init.bootstrapSwitch', this.options.state);
+    }
+
+    _createClass(BootstrapSwitch, [{
+      key: 'setPrevOptions',
+      value: function setPrevOptions() {
+        this.prevOptions = _extends({}, this.options);
+      }
+    }, {
+      key: 'state',
+      value: function state(value, skip) {
+        if (typeof value === 'undefined') {
+          return this.options.state;
+        }
+        if (this.options.disabled || this.options.readonly || this.options.state && !this.options.radioAllOff && this.$element.is(':radio')) {
+          return this.$element;
+        }
+        if (this.$element.is(':radio')) {
+          $('[name="' + this.$element.attr('name') + '"]').trigger('setPreviousOptions.bootstrapSwitch');
+        } else {
+          this.$element.trigger('setPreviousOptions.bootstrapSwitch');
+        }
+        if (this.options.indeterminate) {
+          this.indeterminate(false);
+        }
+        this.$element.prop('checked', Boolean(value)).trigger('change.bootstrapSwitch', skip);
+        return this.$element;
+      }
+    }, {
+      key: 'toggleState',
+      value: function toggleState(skip) {
+        if (this.options.disabled || this.options.readonly) {
+          return this.$element;
+        }
+        if (this.options.indeterminate) {
+          this.indeterminate(false);
+          return this.state(true);
+        } else {
+          return this.$element.prop('checked', !this.options.state).trigger('change.bootstrapSwitch', skip);
+        }
+      }
+    }, {
+      key: 'size',
+      value: function size(value) {
+        if (typeof value === 'undefined') {
+          return this.options.size;
+        }
+        if (this.options.size != null) {
+          this.$wrapper.removeClass(this._getClass(this.options.size));
+        }
+        if (value) {
+          this.$wrapper.addClass(this._getClass(value));
+        }
+        this._width();
+        this._containerPosition();
+        this.options.size = value;
+        return this.$element;
+      }
+    }, {
+      key: 'animate',
+      value: function animate(value) {
+        if (typeof value === 'undefined') {
+          return this.options.animate;
+        }
+        if (this.options.animate === Boolean(value)) {
+          return this.$element;
+        }
+        return this.toggleAnimate();
+      }
+    }, {
+      key: 'toggleAnimate',
+      value: function toggleAnimate() {
+        this.options.animate = !this.options.animate;
+        this.$wrapper.toggleClass(this._getClass('animate'));
+        return this.$element;
+      }
+    }, {
+      key: 'disabled',
+      value: function disabled(value) {
+        if (typeof value === 'undefined') {
+          return this.options.disabled;
+        }
+        if (this.options.disabled === Boolean(value)) {
+          return this.$element;
+        }
+        return this.toggleDisabled();
+      }
+    }, {
+      key: 'toggleDisabled',
+      value: function toggleDisabled() {
+        this.options.disabled = !this.options.disabled;
+        this.$element.prop('disabled', this.options.disabled);
+        this.$wrapper.toggleClass(this._getClass('disabled'));
+        return this.$element;
+      }
+    }, {
+      key: 'readonly',
+      value: function readonly(value) {
+        if (typeof value === 'undefined') {
+          return this.options.readonly;
+        }
+        if (this.options.readonly === Boolean(value)) {
+          return this.$element;
+        }
+        return this.toggleReadonly();
+      }
+    }, {
+      key: 'toggleReadonly',
+      value: function toggleReadonly() {
+        this.options.readonly = !this.options.readonly;
+        this.$element.prop('readonly', this.options.readonly);
+        this.$wrapper.toggleClass(this._getClass('readonly'));
+        return this.$element;
+      }
+    }, {
+      key: 'indeterminate',
+      value: function indeterminate(value) {
+        if (typeof value === 'undefined') {
+          return this.options.indeterminate;
+        }
+        if (this.options.indeterminate === Boolean(value)) {
+          return this.$element;
+        }
+        return this.toggleIndeterminate();
+      }
+    }, {
+      key: 'toggleIndeterminate',
+      value: function toggleIndeterminate() {
+        this.options.indeterminate = !this.options.indeterminate;
+        this.$element.prop('indeterminate', this.options.indeterminate);
+        this.$wrapper.toggleClass(this._getClass('indeterminate'));
+        this._containerPosition();
+        return this.$element;
+      }
+    }, {
+      key: 'inverse',
+      value: function inverse(value) {
+        if (typeof value === 'undefined') {
+          return this.options.inverse;
+        }
+        if (this.options.inverse === Boolean(value)) {
+          return this.$element;
+        }
+        return this.toggleInverse();
+      }
+    }, {
+      key: 'toggleInverse',
+      value: function toggleInverse() {
+        this.$wrapper.toggleClass(this._getClass('inverse'));
+        var $on = this.$on.clone(true);
+        var $off = this.$off.clone(true);
+        this.$on.replaceWith($off);
+        this.$off.replaceWith($on);
+        this.$on = $off;
+        this.$off = $on;
+        this.options.inverse = !this.options.inverse;
+        return this.$element;
+      }
+    }, {
+      key: 'onColor',
+      value: function onColor(value) {
+        if (typeof value === 'undefined') {
+          return this.options.onColor;
+        }
+        if (this.options.onColor) {
+          this.$on.removeClass(this._getClass(this.options.onColor));
+        }
+        this.$on.addClass(this._getClass(value));
+        this.options.onColor = value;
+        return this.$element;
+      }
+    }, {
+      key: 'offColor',
+      value: function offColor(value) {
+        if (typeof value === 'undefined') {
+          return this.options.offColor;
+        }
+        if (this.options.offColor) {
+          this.$off.removeClass(this._getClass(this.options.offColor));
+        }
+        this.$off.addClass(this._getClass(value));
+        this.options.offColor = value;
+        return this.$element;
+      }
+    }, {
+      key: 'onText',
+      value: function onText(value) {
+        if (typeof value === 'undefined') {
+          return this.options.onText;
+        }
+        this.$on.html(value);
+        this._width();
+        this._containerPosition();
+        this.options.onText = value;
+        return this.$element;
+      }
+    }, {
+      key: 'offText',
+      value: function offText(value) {
+        if (typeof value === 'undefined') {
+          return this.options.offText;
+        }
+        this.$off.html(value);
+        this._width();
+        this._containerPosition();
+        this.options.offText = value;
+        return this.$element;
+      }
+    }, {
+      key: 'labelText',
+      value: function labelText(value) {
+        if (typeof value === 'undefined') {
+          return this.options.labelText;
+        }
+        this.$label.html(value);
+        this._width();
+        this.options.labelText = value;
+        return this.$element;
+      }
+    }, {
+      key: 'handleWidth',
+      value: function handleWidth(value) {
+        if (typeof value === 'undefined') {
+          return this.options.handleWidth;
+        }
+        this.options.handleWidth = value;
+        this._width();
+        this._containerPosition();
+        return this.$element;
+      }
+    }, {
+      key: 'labelWidth',
+      value: function labelWidth(value) {
+        if (typeof value === 'undefined') {
+          return this.options.labelWidth;
+        }
+        this.options.labelWidth = value;
+        this._width();
+        this._containerPosition();
+        return this.$element;
+      }
+    }, {
+      key: 'baseClass',
+      value: function baseClass(value) {
+        return this.options.baseClass;
+      }
+    }, {
+      key: 'wrapperClass',
+      value: function wrapperClass(value) {
+        if (typeof value === 'undefined') {
+          return this.options.wrapperClass;
+        }
+        if (!value) {
+          value = $.fn.bootstrapSwitch.defaults.wrapperClass;
+        }
+        this.$wrapper.removeClass(this._getClasses(this.options.wrapperClass).join(' '));
+        this.$wrapper.addClass(this._getClasses(value).join(' '));
+        this.options.wrapperClass = value;
+        return this.$element;
+      }
+    }, {
+      key: 'radioAllOff',
+      value: function radioAllOff(value) {
+        if (typeof value === 'undefined') {
+          return this.options.radioAllOff;
+        }
+        var val = Boolean(value);
+        if (this.options.radioAllOff === val) {
+          return this.$element;
+        }
+        this.options.radioAllOff = val;
+        return this.$element;
+      }
+    }, {
+      key: 'onInit',
+      value: function onInit(value) {
+        if (typeof value === 'undefined') {
+          return this.options.onInit;
+        }
+        if (!value) {
+          value = $.fn.bootstrapSwitch.defaults.onInit;
+        }
+        this.options.onInit = value;
+        return this.$element;
+      }
+    }, {
+      key: 'onSwitchChange',
+      value: function onSwitchChange(value) {
+        if (typeof value === 'undefined') {
+          return this.options.onSwitchChange;
+        }
+        if (!value) {
+          value = $.fn.bootstrapSwitch.defaults.onSwitchChange;
+        }
+        this.options.onSwitchChange = value;
+        return this.$element;
+      }
+    }, {
+      key: 'destroy',
+      value: function destroy() {
+        var $form = this.$element.closest('form');
+        if ($form.length) {
+          $form.off('reset.bootstrapSwitch').removeData('bootstrap-switch');
+        }
+        this.$container.children().not(this.$element).remove();
+        this.$element.unwrap().unwrap().off('.bootstrapSwitch').removeData('bootstrap-switch');
+        return this.$element;
+      }
+    }, {
+      key: '_getElementOptions',
+      value: function _getElementOptions() {
+        return {
+          state: this.$element.is(':checked'),
+          size: this.$element.data('size'),
+          animate: this.$element.data('animate'),
+          disabled: this.$element.is(':disabled'),
+          readonly: this.$element.is('[readonly]'),
+          indeterminate: this.$element.data('indeterminate'),
+          inverse: this.$element.data('inverse'),
+          radioAllOff: this.$element.data('radio-all-off'),
+          onColor: this.$element.data('on-color'),
+          offColor: this.$element.data('off-color'),
+          onText: this.$element.data('on-text'),
+          offText: this.$element.data('off-text'),
+          labelText: this.$element.data('label-text'),
+          handleWidth: this.$element.data('handle-width'),
+          labelWidth: this.$element.data('label-width'),
+          baseClass: this.$element.data('base-class'),
+          wrapperClass: this.$element.data('wrapper-class')
+        };
+      }
+    }, {
+      key: '_width',
+      value: function _width() {
+        var _this2 = this;
+
+        var $handles = this.$on.add(this.$off).add(this.$label).css('width', '');
+        var handleWidth = this.options.handleWidth === 'auto' ? Math.round(Math.max(this.$on.width(), this.$off.width())) : this.options.handleWidth;
+        $handles.width(handleWidth);
+        this.$label.width(function(index, width) {
+          if (_this2.options.labelWidth !== 'auto') {
+            return _this2.options.labelWidth;
+          }
+          if (width < handleWidth) {
+            return handleWidth;
+          }
+          return width;
+        });
+        this._handleWidth = this.$on.outerWidth();
+        this._labelWidth = this.$label.outerWidth();
+        this.$container.width(this._handleWidth * 2 + this._labelWidth);
+        return this.$wrapper.width(this._handleWidth + this._labelWidth);
+      }
+    }, {
+      key: '_containerPosition',
+      value: function _containerPosition() {
+        var _this3 = this;
+
+        var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.options.state;
+        var callback = arguments[1];
+
+        this.$container.css('margin-left', function() {
+          var values = [0, '-' + _this3._handleWidth + 'px'];
+          if (_this3.options.indeterminate) {
+            return '-' + _this3._handleWidth / 2 + 'px';
+          }
+          if (state) {
+            if (_this3.options.inverse) {
+              return values[1];
+            } else {
+              return values[0];
+            }
+          } else {
+            if (_this3.options.inverse) {
+              return values[0];
+            } else {
+              return values[1];
+            }
+          }
+        });
+      }
+    }, {
+      key: '_init',
+      value: function _init() {
+        var _this4 = this;
+
+        var init = function init() {
+          _this4.setPrevOptions();
+          _this4._width();
+          _this4._containerPosition();
+          setTimeout(function() {
+            if (_this4.options.animate) {
+              return _this4.$wrapper.addClass(_this4._getClass('animate'));
+            }
+          }, 50);
+        };
+        if (this.$wrapper.is(':visible')) {
+          init();
+          return;
+        }
+        var initInterval = window.setInterval(function() {
+          if (_this4.$wrapper.is(':visible')) {
+            init();
+            return window.clearInterval(initInterval);
+          }
+        }, 50);
+      }
+    }, {
+      key: '_elementHandlers',
+      value: function _elementHandlers() {
+        var _this5 = this;
+
+        return this.$element.on({
+          'setPreviousOptions.bootstrapSwitch': this.setPrevOptions.bind(this),
+
+          'previousState.bootstrapSwitch': function previousStateBootstrapSwitch() {
+            _this5.options = _this5.prevOptions;
+            if (_this5.options.indeterminate) {
+              _this5.$wrapper.addClass(_this5._getClass('indeterminate'));
+            }
+            _this5.$element.prop('checked', _this5.options.state).trigger('change.bootstrapSwitch', true);
+          },
+
+          'change.bootstrapSwitch': function changeBootstrapSwitch(event, skip) {
+            event.preventDefault();
+            event.stopImmediatePropagation();
+            var state = _this5.$element.is(':checked');
+            _this5._containerPosition(state);
+            if (state === _this5.options.state) {
+              return;
+            }
+            _this5.options.state = state;
+            _this5.$wrapper.toggleClass(_this5._getClass('off')).toggleClass(_this5._getClass('on'));
+            if (!skip) {
+              if (_this5.$element.is(':radio')) {
+                $('[name="' + _this5.$element.attr('name') + '"]').not(_this5.$element).prop('checked', false).trigger('change.bootstrapSwitch', true);
+              }
+              _this5.$element.trigger('switchChange.bootstrapSwitch', [state]);
+            }
+          },
+
+          'focus.bootstrapSwitch': function focusBootstrapSwitch(event) {
+            event.preventDefault();
+            _this5.$wrapper.addClass(_this5._getClass('focused'));
+          },
+
+          'blur.bootstrapSwitch': function blurBootstrapSwitch(event) {
+            event.preventDefault();
+            _this5.$wrapper.removeClass(_this5._getClass('focused'));
+          },
+
+          'keydown.bootstrapSwitch': function keydownBootstrapSwitch(event) {
+            if (!event.which || _this5.options.disabled || _this5.options.readonly) {
+              return;
+            }
+            if (event.which === 37 || event.which === 39) {
+              event.preventDefault();
+              event.stopImmediatePropagation();
+              _this5.state(event.which === 39);
+            }
+          }
+        });
+      }
+    }, {
+      key: '_handleHandlers',
+      value: function _handleHandlers() {
+        var _this6 = this;
+
+        this.$on.on('click.bootstrapSwitch', function(event) {
+          event.preventDefault();
+          event.stopPropagation();
+          _this6.state(false);
+          return _this6.$element.trigger('focus.bootstrapSwitch');
+        });
+        return this.$off.on('click.bootstrapSwitch', function(event) {
+          event.preventDefault();
+          event.stopPropagation();
+          _this6.state(true);
+          return _this6.$element.trigger('focus.bootstrapSwitch');
+        });
+      }
+    }, {
+      key: '_labelHandlers',
+      value: function _labelHandlers() {
+        var _this7 = this;
+
+        var handlers = {
+          click: function click(event) {
+            event.stopPropagation();
+          },
+
+
+          'mousedown.bootstrapSwitch touchstart.bootstrapSwitch': function mousedownBootstrapSwitchTouchstartBootstrapSwitch(event) {
+            if (_this7._dragStart || _this7.options.disabled || _this7.options.readonly) {
+              return;
+            }
+            event.preventDefault();
+            event.stopPropagation();
+            _this7._dragStart = (event.pageX || event.originalEvent.touches[0].pageX) - parseInt(_this7.$container.css('margin-left'), 10);
+            if (_this7.options.animate) {
+              _this7.$wrapper.removeClass(_this7._getClass('animate'));
+            }
+            _this7.$element.trigger('focus.bootstrapSwitch');
+          },
+
+          'mousemove.bootstrapSwitch touchmove.bootstrapSwitch': function mousemoveBootstrapSwitchTouchmoveBootstrapSwitch(event) {
+            if (_this7._dragStart == null) {
+              return;
+            }
+            var difference = (event.pageX || event.originalEvent.touches[0].pageX) - _this7._dragStart;
+            event.preventDefault();
+            if (difference < -_this7._handleWidth || difference > 0) {
+              return;
+            }
+            _this7._dragEnd = difference;
+            _this7.$container.css('margin-left', _this7._dragEnd + 'px');
+          },
+
+          'mouseup.bootstrapSwitch touchend.bootstrapSwitch': function mouseupBootstrapSwitchTouchendBootstrapSwitch(event) {
+            if (!_this7._dragStart) {
+              return;
+            }
+            event.preventDefault();
+            if (_this7.options.animate) {
+              _this7.$wrapper.addClass(_this7._getClass('animate'));
+            }
+            if (_this7._dragEnd) {
+              var state = _this7._dragEnd > -(_this7._handleWidth / 2);
+              _this7._dragEnd = false;
+              _this7.state(_this7.options.inverse ? !state : state);
+            } else {
+              _this7.state(!_this7.options.state);
+            }
+            _this7._dragStart = false;
+          },
+
+          'mouseleave.bootstrapSwitch': function mouseleaveBootstrapSwitch() {
+            _this7.$label.trigger('mouseup.bootstrapSwitch');
+          }
+        };
+        this.$label.on(handlers);
+      }
+    }, {
+      key: '_externalLabelHandler',
+      value: function _externalLabelHandler() {
+        var _this8 = this;
+
+        var $externalLabel = this.$element.closest('label');
+        $externalLabel.on('click', function(event) {
+          event.preventDefault();
+          event.stopImmediatePropagation();
+          if (event.target === $externalLabel[0]) {
+            _this8.toggleState();
+          }
+        });
+      }
+    }, {
+      key: '_formHandler',
+      value: function _formHandler() {
+        var $form = this.$element.closest('form');
+        if ($form.data('bootstrap-switch')) {
+          return;
+        }
+        $form.on('reset.bootstrapSwitch', function() {
+          window.setTimeout(function() {
+            $form.find('input').filter(function() {
+              return $(this).data('bootstrap-switch');
+            }).each(function() {
+              return $(this).bootstrapSwitch('state', this.checked);
+            });
+          }, 1);
+        }).data('bootstrap-switch', true);
+      }
+    }, {
+      key: '_getClass',
+      value: function _getClass(name) {
+        return this.options.baseClass + '-' + name;
+      }
+    }, {
+      key: '_getClasses',
+      value: function _getClasses(classes) {
+        if (!$.isArray(classes)) {
+          return [this._getClass(classes)];
+        }
+        return classes.map(this._getClass.bind(this));
+      }
+    }]);
+
+    return BootstrapSwitch;
+  }();
+
+  $.fn.bootstrapSwitch = function(option) {
+    for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
+      args[_key2 - 1] = arguments[_key2];
+    }
+
+    function reducer(ret, next) {
+      var $this = $(next);
+      var existingData = $this.data('bootstrap-switch');
+      var data = existingData || new BootstrapSwitch(next, option);
+      if (!existingData) {
+        $this.data('bootstrap-switch', data);
+      }
+      if (typeof option === 'string') {
+        return data[option].apply(data, args);
+      }
+      return ret;
+    }
+    return Array.prototype.reduce.call(this, reducer, this);
+  };
+  $.fn.bootstrapSwitch.Constructor = BootstrapSwitch;
+  $.fn.bootstrapSwitch.defaults = {
+    state: true,
+    size: null,
+    animate: true,
+    disabled: false,
+    readonly: false,
+    indeterminate: false,
+    inverse: false,
+    radioAllOff: false,
+    onColor: 'primary',
+    offColor: 'default',
+    onText: 'ON',
+    offText: 'OFF',
+    labelText: '&nbsp',
+    handleWidth: 'auto',
+    labelWidth: 'auto',
+    baseClass: 'bootstrap-switch',
+    wrapperClass: 'wrapper',
+    onInit: function onInit() {},
+    onSwitchChange: function onSwitchChange() {}
+  };
+});

File diff suppressed because it is too large
+ 5 - 0
src/main/resources/static/js/plugins/moment.min.js


File diff suppressed because it is too large
+ 2 - 0
src/main/resources/static/js/plugins/nouislider.min.js


+ 1212 - 0
src/main/resources/templates/index.html

@@ -0,0 +1,1212 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+    <meta charset="utf-8"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
+    <meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, shrink-to-fit=no' name='viewport'/>
+    <link rel="apple-touch-icon" sizes="76x76" href="../static/favicon.ico"/>
+    <link rel="icon" type="image/png" href="../static/favicon.ico"/>
+    <title>Kinect & IoT</title>
+    <!--     Fonts and icons     -->
+    <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700,200" rel="stylesheet"/>
+    <link href="https://maxcdn.bootstrapcdn.com/font-awesome/latest/css/font-awesome.min.css" rel="stylesheet"/>
+    <!-- CSS Files -->
+    <link href="../static/css/bootstrap.min.css" rel="stylesheet"/>
+    <link href="../static/css/paper-kit.css?v=2.2.0" rel="stylesheet"/>
+    <!-- CSS Just for demo purpose, don't include it in your project -->
+    <link href="../static/css/demo.css" rel="stylesheet"/>
+</head>
+
+<body class="index-page sidebar-collapse">
+<!-- Navbar -->
+<nav class="navbar navbar-expand-lg fixed-top navbar-transparent " color-on-scroll="300">
+    <div class="container">
+        <div class="navbar-translate">
+            <a class="navbar-brand" href="#" rel="tooltip" title="Kinect & IoT" data-placement="bottom" target="_blank">
+                Kinect & IoT
+            </a>
+            <button class="navbar-toggler navbar-toggler" type="button" data-toggle="collapse" data-target="#navigation"
+                    aria-controls="navigation-index" aria-expanded="false" aria-label="Toggle navigation">
+                <span class="navbar-toggler-bar bar1"></span>
+                <span class="navbar-toggler-bar bar2"></span>
+                <span class="navbar-toggler-bar bar3"></span>
+            </button>
+        </div>
+        <div class="collapse navbar-collapse justify-content-end" id="navigation">
+            <ul class="navbar-nav">
+                <li class="nav-item">
+                    <a class="nav-link" rel="tooltip" title="Follow us on Twitter" data-placement="bottom" href="https://twitter.com/CreativeTim"
+                       target="_blank">
+                        <i class="fa fa-twitter"></i>
+                        <p class="d-lg-none">Twitter</p>
+                    </a>
+                </li>
+                <li class="nav-item">
+                    <a class="nav-link" rel="tooltip" title="Like us on Facebook" data-placement="bottom" href="https://www.facebook.com/CreativeTim"
+                       target="_blank">
+                        <i class="fa fa-facebook-square"></i>
+                        <p class="d-lg-none">Facebook</p>
+                    </a>
+                </li>
+                <li class="nav-item">
+                    <a class="nav-link" rel="tooltip" title="Follow us on Instagram" data-placement="bottom"
+                       href="https://www.instagram.com/CreativeTimOfficial" target="_blank">
+                        <i class="fa fa-instagram"></i>
+                        <p class="d-lg-none">Instagram</p>
+                    </a>
+                </li>
+                <li class="nav-item">
+                    <a class="nav-link" rel="tooltip" title="Star on GitHub" data-placement="bottom"
+                       href="https://www.github.com/CreativeTimOfficial/paper-kit" target="_blank">
+                        <i class="fa fa-github"></i>
+                        <p class="d-lg-none">GitHub</p>
+                    </a>
+                </li>
+                <li class="nav-item">
+                    <a href="https://demos.creative-tim.com/paper-kit-2/docs/1.0/getting-started/introduction.html" target="_blank"
+                       class="nav-link"><i class="nc-icon nc-book-bookmark"></i> Documentation</a>
+                </li>
+                <li class="nav-item">
+                    <a href="https://www.creative-tim.com/product/paper-kit-2-pro?ref=pk2-free-local" target="_blank"
+                       class="btn btn-danger btn-round">Upgrade to Pro</a>
+                </li>
+            </ul>
+        </div>
+    </div>
+</nav>
+<!-- End Navbar -->
+<div class="page-header section-dark" style="background-image: url('/index-background.jpg')">
+    <div class="filter"></div>
+    <div class="content-center">
+        <div class="container">
+            <div class="title-brand">
+                <h1 class="presentation-title">Kinect & IoT</h1>
+                <div class="fog-low">
+                    <img src="../static/images/fog-low.png" alt=""/>
+                </div>
+                <div class="fog-low right">
+                    <img src="../static/images/fog-low.png" alt=""/>
+                </div>
+            </div>
+            <h2 class="presentation-subtitle text-center">让你的交互方式更酷! 更炫! 更精彩! </h2>
+        </div>
+    </div>
+    <div class="moving-clouds" style="background-image: url('./assets/img/clouds.png'); "></div>
+    <h6 class="category category-absolute">Designed and coded by
+        <a href="https://www.minbb.cn" target="_blank">
+            <img class="creative-tim-logo" src="../static/images/author.png" width="80" alt=""/>
+        </a>
+    </h6>
+</div>
+<div class="main">
+    <div class="section section-buttons">
+        <div class="container">
+            <div class="title">
+                <h2>Basic Elements</h2>
+            </div>
+            <div id="buttons">
+                <div class="title">
+                    <h3>Buttons
+                        <br/>
+                        <small>Pick your style</small>
+                    </h3>
+                </div>
+                <div class="row">
+                    <div class="col-md-8">
+                        <button type="button" class="btn btn-info">Default</button>
+                        <button type="button" class="btn btn-info btn-round">Round</button>
+                        <button type="button" class="btn btn-info btn-round"><i class="fa fa-heart"></i> With Icon</button>
+                        <button type="button" class="btn btn-info btn-just-icon"><i class="fa fa-heart"></i></button>
+                        <button type="button" class="btn btn-info btn-link">Simple</button>
+                    </div>
+                </div>
+                <div class="title">
+                    <h3>
+                        <small>Pick your size</small>
+                    </h3>
+                </div>
+                <div class="row">
+                    <div class="col-md-8">
+                        <button type="button" class="btn btn-outline-danger btn-sm">Small</button>
+                        <button type="button" class="btn btn-outline-danger">Regular</button>
+                        <button type="button" class="btn btn-outline-danger btn-lg">Large</button>
+                    </div>
+                </div>
+                <div class="title">
+                    <h3>
+                        <small>Pick your color</small>
+                    </h3>
+                </div>
+                <div class="row">
+                    <div class="col-md-8">
+                        <button type="button" class="btn btn-outline-default btn-round">Default</button>
+                        <button type="button" class="btn btn-outline-primary btn-round">Primary</button>
+                        <button type="button" class="btn btn-outline-info btn-round">Info</button>
+                        <button type="button" class="btn btn-outline-success btn-round">Success</button>
+                        <button type="button" class="btn btn-outline-warning btn-round">Warning</button>
+                        <button type="button" class="btn btn-outline-danger btn-round">Danger</button>
+                        <button type="button" class="btn btn-outline-neutral btn-round">Neutral</button>
+                    </div>
+                </div>
+                <br/>
+                <div class="row">
+                    <div class="col-md-8">
+                        <button type="button" class="btn btn-default btn-round">Default</button>
+                        <button type="button" class="btn btn-primary btn-round">Primary</button>
+                        <button type="button" class="btn btn-info btn-round">Info</button>
+                        <button type="button" class="btn btn-success btn-round">Success</button>
+                        <button type="button" class="btn btn-warning btn-round">Warning</button>
+                        <button type="button" class="btn btn-danger btn-round">Danger</button>
+                        <button type="button" class="btn btn-neutral btn-round">Neutral</button>
+                    </div>
+                </div>
+            </div>
+            <div class="title">
+                <h3>Links</h3>
+            </div>
+            <div class="row">
+                <div class="col-md-8">
+                    <a href="#0" class="btn btn-link btn-default">Default</a>
+                    <a href="#0" class="btn btn-link btn-primary">Primary</a>
+                    <a href="#0" class="btn btn-link btn-success">Success</a>
+                    <a href="#0" class="btn btn-link btn-info">Info</a>
+                    <a href="#0" class="btn btn-link btn-warning">Warning</a>
+                    <a href="#0" class="btn btn-link btn-danger">Danger</a>
+                    <a href="#0" class="btn btn-link btn-neutral">Neutral</a>
+                </div>
+            </div>
+            <div class="title">
+                <h3>Inputs</h3>
+            </div>
+            <div class="row">
+                <div class="col-sm-3">
+                    <div class="form-group">
+                        <input type="text" class="form-control" placeholder="Default">
+                    </div>
+                </div>
+                <div class="col-sm-3">
+                    <div class="form-group has-success">
+                        <input type="text" class="form-control form-control-success" id="inputSuccess1" value="Success">
+                    </div>
+                </div>
+                <div class="col-sm-3">
+                    <div class="form-group has-danger">
+                        <input type="text" class="form-control form-control-danger" id="inputDanger1" value="Error">
+                        <div class="form-control-feedback">Sorry, that username's taken. Try another?</div>
+                    </div>
+                </div>
+                <div class="col-sm-3">
+                    <div class="input-group">
+                        <input type="text" class="form-control" placeholder="Username">
+                        <div class="input-group-append">
+                            <span class="input-group-text"><i class="fa fa-group" aria-hidden="true"></i></span>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <br/>
+            <div class="row">
+                <div class="col-sm-6 col-lg-3">
+                    <div class="title">
+                        <h3>Checkboxes</h3>
+                    </div>
+                    <div class="form-check">
+                        <label class="form-check-label">
+                            <input class="form-check-input" type="checkbox" value=""> Unchecked
+                            <span class="form-check-sign"></span>
+                        </label>
+                    </div>
+                    <div class="form-check">
+                        <label class="form-check-label">
+                            <input class="form-check-input" type="checkbox" value="" checked> Checked
+                            <span class="form-check-sign"></span>
+                        </label>
+                    </div>
+                    <div class="form-check disabled">
+                        <label class="form-check-label">
+                            <input class="form-check-input" type="checkbox" value="" disabled> Disabled unchecked
+                            <span class="form-check-sign"></span>
+                        </label>
+                    </div>
+                    <div class="form-check disabled">
+                        <label class="form-check-label">
+                            <input class="form-check-input" type="checkbox" value="" disabled checked> Disabled checked
+                            <span class="form-check-sign"></span>
+                        </label>
+                    </div>
+                </div>
+                <div class="col-sm-6 col-lg-3">
+                    <div class="title">
+                        <h3>Radio Buttons</h3>
+                    </div>
+                    <div class="form-check-radio">
+                        <label class="form-check-label">
+                            <input class="form-check-input" type="radio" name="exampleRadios" id="exampleRadios1" value="option1"> Radio is off
+                            <span class="form-check-sign"></span>
+                        </label>
+                    </div>
+                    <div class="form-check-radio">
+                        <label class="form-check-label">
+                            <input class="form-check-input" type="radio" name="exampleRadios" id="exampleRadios2" value="option2" checked> Radio is on
+                            <span class="form-check-sign"></span>
+                        </label>
+                    </div>
+                    <div class="form-check-radio disabled">
+                        <label class="form-check-label">
+                            <input class="form-check-input" type="radio" name="exampleRadios" id="exampleRadios3" value="option3" disabled> Disabled
+                            radio is off
+                            <span class="form-check-sign"></span>
+                        </label>
+                    </div>
+                    <div class="form-check-radio disabled">
+                        <label class="form-check-label">
+                            <input class="form-check-input" type="radio" name="exampleRadioz" id="exampleRadios4" value="option4" checked disabled>
+                            Disabled radio is on
+                            <span class="form-check-sign"></span>
+                        </label>
+                    </div>
+                </div>
+                <div class="col-sm-6 col-lg-3">
+                    <div class="title">
+                        <h3>Toggle Buttons</h3>
+                    </div>
+                    <div id="switches">
+                        <label>
+                            <input type="checkbox" data-toggle="switch" checked="" data-on-color="primary" data-off-color="primary">
+                            <span class="toggle"></span>
+                        </label>
+                        <br/>
+                        <label>
+                            <input type="checkbox" data-toggle="switch" data-off-color="primary" data-on-color="primary">
+                            <span class="toggle"></span>
+                        </label>
+                    </div>
+                </div>
+                <div class="col-sm-6 col-lg-3">
+                    <div class="title">
+                        <h3>Sliders</h3>
+                    </div>
+                    <div id="sliderRegular" class="slider"></div>
+                    <br>
+                    <div id="sliderDouble" class="slider slider-primary"></div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="section section-navbars">
+        <div class="container" id="menu-dropdown">
+            <div class="title">
+                <h3>Menu</h3>
+            </div>
+            <br/>
+            <div class="row">
+                <div class="col-md-6">
+                    <nav class="navbar navbar-expand-lg bg-primary">
+                        <a class="navbar-brand" href="#">Menu</a>
+                        <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbar-menu"
+                                aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
+                            <span class="navbar-toggler-bar"></span>
+                            <span class="navbar-toggler-bar"></span>
+                            <span class="navbar-toggler-bar"></span>
+                        </button>
+                        <div class="collapse navbar-collapse" id="navbar-menu">
+                            <ul class="navbar-nav mr-auto">
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#pk">Link</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#pk">Link</a>
+                                </li>
+                                <div class="nav-item dropdown">
+                                    <a class="nav-link dropdown-toggle" data-toggle="dropdown" id="dropdownMenuButton" href="#pk" role="button"
+                                       aria-haspopup="true" aria-expanded="false">Dropdown</a>
+                                    <ul class="dropdown-menu dropdown-info" aria-labelledby="dropdownMenuButton">
+                                        <li class="dropdown-header">Dropdown header</li>
+                                        <a class="dropdown-item" href="#pk">Action</a>
+                                        <a class="dropdown-item" href="#pk">Another action</a>
+                                        <a class="dropdown-item" href="#pk">Something else here</a>
+                                        <div class="dropdown-divider"></div>
+                                        <a class="dropdown-item" href="#pk">Separated link</a>
+                                        <div class="dropdown-divider"></div>
+                                        <a class="dropdown-item" href="#pk">Another separated link</a>
+                                    </ul>
+                                </div>
+                            </ul>
+                        </div>
+                    </nav>
+                </div>
+                <div class="col-md-6">
+                    <nav class="navbar navbar-expand-lg bg-danger">
+                        <a class="navbar-brand" href="#">Icons</a>
+                        <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbar-menu-icon"
+                                aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
+                            <span class="navbar-toggler-bar"></span>
+                            <span class="navbar-toggler-bar"></span>
+                            <span class="navbar-toggler-bar"></span>
+                        </button>
+                        <div class="collapse navbar-collapse" id="navbar-menu-icon">
+                            <ul class="navbar-nav ml-auto">
+                                <li class="nav-item active">
+                                    <a class="nav-link" href="#pk"><i class="nc-icon nc-email-85" aria-hidden="true"></i></a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#pk"><i class="nc-icon nc-single-02" aria-hidden="true"></i></a>
+                                </li>
+                                <div class="nav-item dropdown">
+                                    <a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#pk" role="button" aria-haspopup="true"
+                                       aria-expanded="false"><i class="nc-icon nc-settings-gear-65" aria-hidden="true"></i></a>
+                                    <ul class="dropdown-menu dropdown-menu-right dropdown-danger">
+                                        <li class="dropdown-header" href="#pk">Dropdown header</li>
+                                        <a class="dropdown-item" href="#pk">Another action</a>
+                                        <a class="dropdown-item" href="#pk">Something else here</a>
+                                        <div class="dropdown-divider"></div>
+                                        <a class="dropdown-item" href="#pk">Separated link</a>
+                                    </ul>
+                                </div>
+                            </ul>
+                        </div>
+                    </nav>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="section section-navigation">
+        <div class="container tim-container">
+            <div class="title">
+                <h3>Navigation Areas</h3>
+            </div>
+        </div>
+        <div id="navbar">
+            <div class="navigation-example" style="background-image: url('./assets/img/ilya-yakover.jpg');">
+                <nav class="navbar navbar-expand-lg bg-primary">
+                    <div class="container">
+                        <a class="navbar-brand" href="#">Primary Color</a>
+                        <button class="navbar-toggler navbar-toggler-right burger-menu" type="button" data-toggle="collapse"
+                                data-target="#navbar-primary" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
+                            <span class="navbar-toggler-bar"></span>
+                            <span class="navbar-toggler-bar"></span>
+                            <span class="navbar-toggler-bar"></span>
+                        </button>
+                        <div class="collapse navbar-collapse" id="navbar-primary">
+                            <ul class="navbar-nav ml-auto">
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#"><i class="nc-icon nc-compass-05" aria-hidden="true"></i>&nbsp;Discover</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#"><i class="nc-icon nc-single-02" aria-hidden="true"></i>&nbsp;Profile</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#"><i class="nc-icon nc-settings-gear-65" aria-hidden="true"></i>&nbsp;Settings</a>
+                                </li>
+                            </ul>
+                        </div>
+                    </div>
+                </nav>
+                <nav class="navbar navbar-expand-lg bg-info">
+                    <div class="container">
+                        <a class="navbar-brand" href="#">Info Color</a>
+                        <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbar-info"
+                                aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
+                            <span class="navbar-toggler-bar"></span>
+                            <span class="navbar-toggler-bar"></span>
+                            <span class="navbar-toggler-bar"></span>
+                        </button>
+                        <div class="collapse navbar-collapse" id="navbar-info">
+                            <ul class="navbar-nav ml-auto">
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#">Discover</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#">Profile</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#">Settings</a>
+                                </li>
+                            </ul>
+                        </div>
+                    </div>
+                </nav>
+                <nav class="navbar navbar-expand-lg bg-success">
+                    <div class="container">
+                        <a class="navbar-brand" href="#">Success Color</a>
+                        <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbar-success"
+                                aria-controls="navbarNav" aria-expanded="true" aria-label="Toggle navigation">
+                            <span class="navbar-toggler-bar"></span>
+                            <span class="navbar-toggler-bar"></span>
+                            <span class="navbar-toggler-bar"></span>
+                        </button>
+                        <div class="navbar-collapse collapse show" id="navbar-success" style="">
+                            <ul class="navbar-nav ml-auto">
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#"><i class="nc-icon nc-compass-05" aria-hidden="true"></i></a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#"><i class="nc-icon nc-single-02" aria-hidden="true"></i> </a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#"><i class="nc-icon nc-settings-gear-65" aria-hidden="true"></i></a>
+                                </li>
+                            </ul>
+                        </div>
+                    </div>
+                </nav>
+                <nav class="navbar navbar-expand-lg bg-warning">
+                    <div class="container">
+                        <a class="navbar-brand" href="#">Warning Color</a>
+                        <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbar-warning"
+                                aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
+                            <span class="navbar-toggler-bar"></span>
+                            <span class="navbar-toggler-bar"></span>
+                            <span class="navbar-toggler-bar"></span>
+                        </button>
+                        <div class="collapse navbar-collapse" id="navbar-warning">
+                            <ul class="navbar-nav ml-auto">
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#"><i class="fa fa-facebook-official" aria-hidden="true"></i></a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#"><i class="fa fa-twitter" aria-hidden="true"></i></a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#"><i class="fa fa-google-plus" aria-hidden="true"></i></a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#"><i class="fa fa-instagram" aria-hidden="true"></i></a>
+                                </li>
+                            </ul>
+                        </div>
+                    </div>
+                </nav>
+                <nav class="navbar navbar-expand-lg bg-danger">
+                    <div class="container">
+                        <a class="navbar-brand" href="#">Danger Color</a>
+                        <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbar-danger"
+                                aria-controls="navbarNav" aria-expanded="true" aria-label="Toggle navigation">
+                            <span class="navbar-toggler-bar"></span>
+                            <span class="navbar-toggler-bar"></span>
+                            <span class="navbar-toggler-bar"></span>
+                        </button>
+                        <div class="navbar-collapse collapse show" id="navbar-danger" style="">
+                            <ul class="navbar-nav ml-auto">
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#"><i class="fa fa-facebook-official" aria-hidden="true"></i> Share</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#"><i class="fa fa-twitter" aria-hidden="true"></i> Tweet</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#"><i class="fa fa-pinterest" aria-hidden="true"></i> Pin</a>
+                                </li>
+                            </ul>
+                        </div>
+                    </div>
+                </nav>
+                <nav class="navbar navbar-expand-lg navbar-transparent pt-0">
+                    <div class="container">
+                        <a class="navbar-brand" href="#">Transparent</a>
+                        <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbar-transparent"
+                                aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
+                            <span class="navbar-toggler-bar"></span>
+                            <span class="navbar-toggler-bar"></span>
+                            <span class="navbar-toggler-bar"></span>
+                        </button>
+                        <div class="collapse navbar-collapse" id="navbar-transparent">
+                            <ul class="navbar-nav ml-auto">
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#"><i class="fa fa-facebook-official" aria-hidden="true"></i> Facebook</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#"><i class="fa fa-twitter" aria-hidden="true"></i> Twitter</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" href="#"><i class="fa fa-instagram" aria-hidden="true"></i> Instagram</a>
+                                </li>
+                            </ul>
+                        </div>
+                    </div>
+                </nav>
+            </div>
+        </div>
+    </div>
+    <div class="section">
+        <div class="container">
+            <div class="row">
+                <div class="col-md-6">
+                    <div class="title">
+                        <h3>Progress Bar</h3>
+                        <br>
+                    </div>
+                    <div class="progress">
+                        <div class="progress-bar progress-bar-success" role="progressbar" style="width: 25%" aria-valuenow="25" aria-valuemin="0"
+                             aria-valuemax="100"></div>
+                    </div>
+                    <br>
+                    <div class="progress">
+                        <div class="progress-bar progress-bar-info" role="progressbar" style="width: 50%" aria-valuenow="50" aria-valuemin="0"
+                             aria-valuemax="100"></div>
+                    </div>
+                    <br>
+                    <div class="progress">
+                        <div class="progress-bar progress-bar-danger" role="progressbar" style="width: 100%" aria-valuenow="100" aria-valuemin="0"
+                             aria-valuemax="100"></div>
+                    </div>
+                    <br>
+                    <div class="progress">
+                        <div class="progress-bar" role="progressbar" style="width: 15%" aria-valuenow="15" aria-valuemin="0"
+                             aria-valuemax="100"></div>
+                        <div class="progress-bar progress-bar-success" role="progressbar" style="width: 30%" aria-valuenow="30" aria-valuemin="0"
+                             aria-valuemax="100"></div>
+                        <div class="progress-bar progress-bar-warning" role="progressbar" style="width: 20%" aria-valuenow="20" aria-valuemin="0"
+                             aria-valuemax="100"></div>
+                    </div>
+                </div>
+                <div class="col-md-6">
+                    <div class="title">
+                        <h3>Pagination</h3>
+                        <br>
+                    </div>
+                    <nav aria-label="Page navigation example">
+                        <ul class="pagination">
+                            <li class="page-item">
+                                <a class="page-link" href="#" aria-label="Previous">
+                                    <i class="fa fa-angle-left" aria-hidden="true"></i>
+                                    <span class="sr-only">Previous</span>
+                                </a>
+                            </li>
+                            <li class="page-item">
+                                <a class="page-link" href="#">1</a>
+                            </li>
+                            <li class="page-item">
+                                <a class="page-link" href="#">2</a>
+                            </li>
+                            <li class="page-item">
+                                <a class="page-link" href="#">3</a>
+                            </li>
+                            <li class="page-item">
+                                <a class="page-link" href="#">4</a>
+                            </li>
+                            <li class="page-item">
+                                <a class="page-link" href="#">5</a>
+                            </li>
+                            <li class="page-item">
+                                <a class="page-link" href="#" aria-label="Next">
+                                    <i class="fa fa-angle-right" aria-hidden="true"></i>
+                                    <span class="sr-only">Next</span>
+                                </a>
+                            </li>
+                        </ul>
+                    </nav>
+                    <br>
+                    <nav aria-label="...">
+                        <ul class="pagination">
+                            <li class="page-item">
+                                <a class="page-link" href="#" tabindex="-1">Previous</a>
+                            </li>
+                            <li class="page-item">
+                                <a class="page-link" href="#">1</a>
+                            </li>
+                            <li class="page-item">
+                                <a class="page-link" href="#">2</a>
+                            </li>
+                            <li class="page-item active">
+                                <a class="page-link" href="#">3
+                                    <span class="sr-only">(current)</span>
+                                </a>
+                            </li>
+                            <li class="page-item">
+                                <a class="page-link" href="#">4</a>
+                            </li>
+                            <li class="page-item">
+                                <a class="page-link" href="#">5</a>
+                            </li>
+                            <li class="page-item">
+                                <a class="page-link" href="#">Next</a>
+                            </li>
+                        </ul>
+                    </nav>
+                </div>
+            </div>
+            <br>
+            <div class="row">
+                <div class="col-md-6">
+                    <div class="title">
+                        <h3>Navigation Tabs</h3>
+                    </div>
+                    <div class="nav-tabs-navigation">
+                        <div class="nav-tabs-wrapper">
+                            <ul id="tabs" class="nav nav-tabs" role="tablist">
+                                <li class="nav-item">
+                                    <a class="nav-link active" data-toggle="tab" href="#home" role="tab">Home</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" data-toggle="tab" href="#profile" role="tab">Profile</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" data-toggle="tab" href="#messages" role="tab">Messages</a>
+                                </li>
+                            </ul>
+                        </div>
+                    </div>
+                    <div id="my-tab-content" class="tab-content text-center">
+                        <div class="tab-pane active" id="home" role="tabpanel">
+                            <p>Larger, yet dramatically thinner. More powerful, but remarkably power efficient. With a smooth metal surface that
+                                seamlessly meets the new Retina HD display.</p>
+                        </div>
+                        <div class="tab-pane" id="profile" role="tabpanel">
+                            <p>Here is your profile.</p>
+                        </div>
+                        <div class="tab-pane" id="messages" role="tabpanel">
+                            <p>Here are your messages.</p>
+                        </div>
+                    </div>
+                </div>
+                <div class="col-md-6">
+                    <div class="title">
+                        <h3>Labels</h3>
+                    </div>
+                    <span class="label label-default">Default</span>
+                    <span class="label label-primary">Primary</span>
+                    <span class="label label-info">Info</span>
+                    <span class="label label-success">Success</span>
+                    <span class="label label-warning">Warning</span>
+                    <span class="label label-danger">Danger</span>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="container tim-container">
+        <div class="title">
+            <h3>Notifications</h3>
+        </div>
+    </div>
+    <div id="notifications">
+        <div class="alert alert-info">
+            <div class="container">
+                <span>This is a plain notification! </span>
+            </div>
+        </div>
+        <div class="alert alert-success">
+            <div class="container">
+                <button type="button" class="close" data-dismiss="alert" aria-label="Close">
+                    <i class="nc-icon nc-simple-remove"></i>
+                </button>
+                <span>This is a notification with close button. </span>
+            </div>
+        </div>
+        <div class="alert alert-warning alert-with-icon" data-notify="container">
+            <div class="container">
+                <div class="alert-wrapper">
+                    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
+                        <i class="nc-icon nc-simple-remove"></i>
+                    </button>
+                    <div class="message"><i class="nc-icon nc-bell-55"></i> This is a notification with close button and icon.</div>
+                </div>
+            </div>
+        </div>
+        <div class="alert alert-danger alert-with-icon" data-notify="container">
+            <div class="container">
+                <div class="alert-wrapper">
+                    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
+                        <i class="nc-icon nc-simple-remove"></i>
+                    </button>
+                    <div class="message"><i class="nc-icon nc-bell-55"></i> This is a notification with close button and icon and have many lines. You
+                        can see that the icon and the close button are always vertically aligned. This is a beautiful notification. So you don't have
+                        to worry about the style.
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!--  end notifications -->
+    <div class="container tim-container">
+        <div class="title">
+            <h3>Typography</h3>
+        </div>
+        <div id="typography">
+            <div class="row">
+                <div class="typography-line">
+                    <h1>
+                        <span class="note">Header 1</span> Thinking in textures
+                    </h1>
+                </div>
+                <div class="typography-line">
+                    <h2>
+                        <span class="note">Header 2</span> Thinking in textures
+                    </h2>
+                </div>
+                <div class="typography-line">
+                    <h3>
+                        <span class="note">Header 3</span> Thinking in textures
+                    </h3>
+                </div>
+                <div class="typography-line">
+                    <h4>
+                        <span class="note">Header 4</span> Thinking in textures
+                    </h4>
+                </div>
+                <div class="typography-line">
+                    <h5>
+                        <span class="note">Header 5</span> Thinking in textures
+                    </h5>
+                </div>
+                <div class="typography-line">
+                    <h6>
+                        <span class="note">Header 6</span> Thinking in textures
+                    </h6>
+                </div>
+                <div class="typography-line">
+                    <p>
+                        <span class="note">Paragraph</span> Thinking in textures
+                    </p>
+                </div>
+                <div class="typography-line">
+                    <span class="note">Quote</span>
+                    <blockquote class="blockquote">
+                        <p class="mb-0">Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
+                            dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam.</p>
+                        <br/>
+                        <footer class="blockquote-footer">Someone famous in
+                            <cite title="source Title">Source Title</cite>
+                        </footer>
+                    </blockquote>
+                </div>
+                <div class="typography-line">
+                    <span class="note">Muted text</span>
+                    <p class="text-muted">Fusce dapibus, tellus ac cursus commodo, tortor mauris nibh.</p>
+                </div>
+                <div class="typography-line">
+                    <span class="note">Primary text</span>
+                    <p class="text-primary">Nullam id dolor id nibh ultricies vehicula ut id elit.</p>
+                </div>
+                <div class="typography-line">
+                    <span class="note">Success text</span>
+                    <p class="text-success">Duis mollis, est non commodo luctus, nisi erat porttitor ligula.</p>
+                </div>
+                <div class="typography-line">
+                    <span class="note">Info text</span>
+                    <p class="text-info">Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
+                </div>
+                <div class="typography-line">
+                    <span class="note">Warning text</span>
+                    <p class="text-warning">Etiam porta sem malesuada magna mollis euismod.</p>
+                </div>
+                <div class="typography-line">
+                    <span class="note">Danger text</span>
+                    <p class="text-danger">Donec ullamcorper nulla non metus auctor fringilla.</p>
+                </div>
+                <div class="typography-line">
+                    <h2>
+                        <span class="note">Small tag</span>Header with small subtitle
+                        <br/>
+                        <small>".small" is a tag for the headers</small>
+                    </h2>
+                </div>
+            </div>
+        </div>
+        <br/>
+        <div id="images">
+            <div class="container">
+                <div class="title">
+                    <h3>Images</h3>
+                </div>
+                <div class="row">
+                    <div class="col-sm-6 col-md-3">
+                        <h4 class="images-title">Rounded Image</h4>
+                        <img src="./assets/img/uriel-soberanes.jpg" class="img-rounded img-responsive" alt="Rounded Image">
+                        <div class="img-details">
+                            <div class="author">
+                                <img src="./assets/img/faces/joe-gardner-2.jpg" alt="Circle Image" class="img-circle img-no-padding img-responsive">
+                            </div>
+                            <p>Sonia Green </p>
+                        </div>
+                    </div>
+                    <div class="col-sm-3 col-md-2 mr-auto ml-auto">
+                        <h4 class="images-title">Circle Image</h4>
+                        <img src="./assets/img/faces/kaci-baum-2.jpg" class="img-circle img-no-padding img-responsive" alt="Rounded Image">
+                        <p class="text-center">Brigitte Bardot</p>
+                    </div>
+                    <div class="col-sm-3 col-md-2 mr-auto">
+                        <h4 class="images-title">Thumbnail</h4>
+                        <img src="./assets/img/faces/erik-lucatero-2.jpg" class="img-thumbnail img-responsive" alt="Rounded Image">
+                        <p class="text-center">John Keynes</p>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="section javascript-components">
+        <div class="container">
+            <div class="title">
+                <h2>Javascript Components</h2>
+            </div>
+            <div class="row" id="modals">
+                <div class="col-md-6">
+                    <div class="title">
+                        <h3>Modal</h3>
+                    </div>
+                    <!-- Button trigger modal -->
+                    <button type="button" class="btn btn-outline-danger btn-round" data-toggle="modal" data-target="#myModal">
+                        Launch demo modal
+                    </button>
+                    <!-- Modal -->
+                    <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
+                        <div class="modal-dialog" role="document">
+                            <div class="modal-content">
+                                <div class="modal-header">
+                                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                                        <span aria-hidden="true">×</span>
+                                    </button>
+                                    <h5 class="modal-title text-center" id="exampleModalLabel">Modal title</h5>
+                                </div>
+                                <div class="modal-body"> Far far away, behind the word mountains, far from the countries Vokalia and Consonantia,
+                                    there live the blind texts. Separated they live in Bookmarksgrove right at the coast of the Semantics, a large
+                                    language ocean. A small river named Duden flows by their place and supplies it with the necessary regelialia. It
+                                    is a paradisematic country, in which roasted parts of sentences fly into your mouth. Even the all-powerful
+                                    Pointing has no control about the blind texts it is an almost unorthographic life One day however a small line of
+                                    blind text by the name of Lorem Ipsum decided to leave for the far World of Grammar.
+                                </div>
+                                <div class="modal-footer">
+                                    <div class="left-side">
+                                        <button type="button" class="btn btn-default btn-link" data-dismiss="modal">Never mind</button>
+                                    </div>
+                                    <div class="divider"></div>
+                                    <div class="right-side">
+                                        <button type="button" class="btn btn-danger btn-link">Delete</button>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="col-md-6">
+                    <div class="title">
+                        <h3>Popovers</h3>
+                    </div>
+                    <button type="button" class="btn btn-round btn-outline-danger" data-toggle="popover" data-placement="top" title="Popover on top"
+                            data-content="Here will be some very useful information about this popover.">On top
+                    </button>
+                    <button type="button" class="btn btn-round btn-outline-danger" data-toggle="popover" data-placement="bottom"
+                            title="Popover on bottom" data-content="Here will be some very useful information about this popover.">On bottom
+                    </button>
+                    <button type="button" class="btn btn-round btn-outline-danger" data-toggle="popover" data-placement="left" title="Popover on left"
+                            data-content="Here will be some very useful information about this popover.">On left
+                    </button>
+                    <button type="button" class="btn btn-round btn-outline-danger" data-toggle="popover" data-placement="right"
+                            title="Popover on right" data-content="Here will be some very useful information about this popover.">On right
+                    </button>
+                </div>
+                <br>
+                <div class="col-md-6">
+                    <div class="title">
+                        <h3>Datepicker</h3>
+                    </div>
+                    <div class="row">
+                        <div class="col-sm-6">
+                            <div class="form-group">
+                                <div class="input-group date" id="datetimepicker">
+                                    <input type="text" class="form-control datetimepicker" placeholder="27/03/2019"/>
+                                    <div class="input-group-append">
+                      <span class="input-group-text">
+                        <span class="glyphicon glyphicon-calendar"><i class="fa fa-calendar" aria-hidden="true"></i></span>
+                      </span>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="col-md-6">
+                    <div class="title">
+                        <h3>Tooltips</h3>
+                    </div>
+                    <button type="button" class="btn btn-outline-danger btn-round" data-toggle="tooltip" data-placement="left" title="On left">On
+                        left
+                    </button>
+                    <button type="button" class="btn btn-outline-danger btn-round" data-toggle="tooltip" data-placement="right" title="On right">On
+                        right
+                    </button>
+                    <button type="button" class="btn btn-outline-danger btn-round" data-toggle="tooltip" data-placement="top" title="On top">On top
+                    </button>
+                    <button type="button" class="btn btn-outline-danger btn-round" data-toggle="tooltip" data-placement="bottom" title="On bottom">On
+                        bottom
+                    </button>
+                </div>
+            </div>
+            <div class="title">
+                <h3>Carousel</h3>
+            </div>
+        </div>
+    </div>
+    <div class="section pt-o" id="carousel">
+        <div class="container">
+            <div class="row">
+                <div class="col-md-8 ml-auto mr-auto">
+                    <div class="card page-carousel">
+                        <div id="carouselExampleIndicators" class="carousel slide" data-ride="carousel">
+                            <ol class="carousel-indicators">
+                                <li data-target="#carouselExampleIndicators" data-slide-to="0" class="active"></li>
+                                <li data-target="#carouselExampleIndicators" data-slide-to="1"></li>
+                                <li data-target="#carouselExampleIndicators" data-slide-to="2"></li>
+                            </ol>
+                            <div class="carousel-inner" role="listbox">
+                                <div class="carousel-item active">
+                                    <img class="d-block img-fluid" src="./assets/img/soroush-karimi.jpg" alt="First slide">
+                                    <div class="carousel-caption d-none d-md-block">
+                                        <p>Somewhere</p>
+                                    </div>
+                                </div>
+                                <div class="carousel-item">
+                                    <img class="d-block img-fluid" src="./assets/img/federico-beccari.jpg" alt="Second slide">
+                                    <div class="carousel-caption d-none d-md-block">
+                                        <p>Somewhere else</p>
+                                    </div>
+                                </div>
+                                <div class="carousel-item">
+                                    <img class="d-block img-fluid" src="./assets/img/joshua-stannard.jpg" alt="Third slide">
+                                    <div class="carousel-caption d-none d-md-block">
+                                        <p>Here it is</p>
+                                    </div>
+                                </div>
+                            </div>
+                            <a class="left carousel-control carousel-control-prev" href="#carouselExampleIndicators" role="button" data-slide="prev">
+                                <span class="fa fa-angle-left"></span>
+                                <span class="sr-only">Previous</span>
+                            </a>
+                            <a class="right carousel-control carousel-control-next" href="#carouselExampleIndicators" role="button" data-slide="next">
+                                <span class="fa fa-angle-right"></span>
+                                <span class="sr-only">Next</span>
+                            </a>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="section section-dark section-nucleo-icons">
+        <div class="container">
+            <div class="row">
+                <div class="col-lg-6 col-md-12">
+                    <h2 class="title">Nucleo Icons</h2>
+                    <br/>
+                    <p class="description">
+                        Paper Kit comes with 100 custom icons made by our friends from NucleoApp. The official package contains over 2.100 thin icons
+                        which are looking great in combination with Paper Kit Make sure you check all of them and use those that you like the most.
+                    </p>
+                    <br/>
+                    <a href="nucleo-icons.html" class="btn btn-danger btn-round" target="_blank">View Demo Icons</a>
+                    <a href="https://nucleoapp.com/?ref=1712" class="btn btn-outline-danger btn-round" target="_blank">View All Icons</a>
+                </div>
+                <div class="col-lg-6 col-md-12">
+                    <div class="icons-container">
+                        <i class="nc-icon nc-time-alarm"></i>
+                        <i class="nc-icon nc-atom"></i>
+                        <i class="nc-icon nc-camera-compact"></i>
+                        <i class="nc-icon nc-watch-time"></i>
+                        <i class="nc-icon nc-key-25"></i>
+                        <i class="nc-icon nc-diamond"></i>
+                        <i class="nc-icon nc-user-run"></i>
+                        <i class="nc-icon nc-layout-11"></i>
+                        <i class="nc-icon nc-badge"></i>
+                        <i class="nc-icon nc-bulb-63"></i>
+                        <i class="nc-icon nc-favourite-28"></i>
+                        <i class="nc-icon nc-planet"></i>
+                        <i class="nc-icon nc-tie-bow"></i>
+                        <i class="nc-icon nc-zoom-split"></i>
+                        <i class="nc-icon nc-cloud-download-93"></i>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="section section-dark">
+        <div class="container">
+            <div class="row">
+                <div class="col-md-8 ml-auto mr-auto text-center">
+                    <h2 class="title">Completed with examples</h2>
+                    <p class="description">The kit comes with three pre-built pages to help you get started faster. You can change the text and images
+                        and you're good to go. More importantly, looking at them will give you a picture of what you can built with this powerful
+                        kit.</p>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="section section-image section-login" style="background-image: url('./assets/img/login-image.jpg');">
+        <div class="container">
+            <div class="row">
+                <div class="col-lg-4 col-md-6 mx-auto">
+                    <div class="card card-register">
+                        <h3 class="title mx-auto">Welcome</h3>
+                        <div class="social-line text-center">
+                            <a href="#pablo" class="btn btn-neutral btn-facebook btn-just-icon mt-0">
+                                <i class="fa fa-facebook-square"></i>
+                            </a>
+                            <a href="#pablo" class="btn btn-neutral btn-google btn-just-icon mt-0">
+                                <i class="fa fa-google-plus"></i>
+                            </a>
+                            <a href="#pablo" class="btn btn-neutral btn-twitter btn-just-icon mt-0">
+                                <i class="fa fa-twitter"></i>
+                            </a>
+                        </div>
+                        <form class="register-form">
+                            <label>Email</label>
+                            <div class="input-group form-group-no-border">
+                                <div class="input-group-prepend">
+                    <span class="input-group-text">
+                      <i class="nc-icon nc-email-85"></i>
+                    </span>
+                                </div>
+                                <input type="email" class="form-control" placeholder="Email">
+                            </div>
+                            <label>Password</label>
+                            <div class="input-group form-group-no-border">
+                                <div class="input-group-prepend">
+                    <span class="input-group-text">
+                      <i class="nc-icon nc-key-25"></i>
+                    </span>
+                                </div>
+                                <input type="password" class="form-control" placeholder="Password">
+                            </div>
+                            <button class="btn btn-danger btn-block btn-round">Register</button>
+                        </form>
+                        <div class="forgot">
+                            <a href="#" class="btn btn-link btn-danger">Forgot password?</a>
+                        </div>
+                    </div>
+                    <div class="col text-center">
+                        <a href="./examples/register-page.html" class="btn btn-outline-neutral btn-round btn-lg" target="_blank">View Register
+                            Page</a>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="section section-dark">
+        <div class="container">
+            <div class="row example-page">
+                <div class="col-md-6 text-center">
+                    <a href="examples/landing.html" target="_blank">
+                        <img src="./assets/img/examples/landing-page.png" alt="Rounded Image" class="img-rounded img-responsive" style="width: 100%">
+                        <a href="./examples/landing-page.html" class="btn btn-outline-neutral btn-round" target="_blank">Landing Page</a>
+                    </a>
+                </div>
+                <div class="col-md-6 text-center">
+                    <a href="examples/profile.html" target="_blank">
+                        <img src="./assets/img/examples/profile-page.png" alt="Rounded Image" class="img-rounded img-responsive" style="width: 100%">
+                        <a href="./examples/profile-page.html" class="btn btn-outline-neutral btn-round" target="_blank">Profile Page</a>
+                    </a>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="section">
+        <div class="container text-center">
+            <div class="row">
+                <div class="col-md-8 ml-auto mr-auto text-center">
+                    <h2 class="title">有兴趣尝试吗?</h2>
+                    <p class="description">当然,如果你尝试一下,你一定会发现一个全新的世界!</p>
+                </div>
+                <div class="col-md-5 ml-auto mr-auto download-area">
+                    <a href="http://www.creative-tim.com/product/paper-kit-2" class="btn btn-danger btn-round">下载体感识别软件</a>
+                </div>
+            </div>
+            <div class="row text-center upgrade-pro">
+                <div class="col-md-8 ml-auto mr-auto">
+                    <h2 class="title">想了解更多吗?</h2>
+                    <p class="description">
+                        我们刚刚推出了
+                        <a class="text-danger" href="#" target="_blank">Kinect & IoT Car</a>
+                        它是一个真正的集成了物联网与体感识别技术的汽车控制系统。
+                    </p>
+                </div>
+                <div class="col-sm-5 ml-auto mr-auto">
+                    <a class="btn btn-info btn-round" href="#" target="_blank">
+                        <i class="nc-icon nc-spaceship" aria-hidden="true"></i> 详细了解
+                    </a>
+                </div>
+            </div>
+            <div class="row justify-content-md-center sharing-area text-center">
+                <div class="text-center col-md-12 col-lg-8">
+                    <h3>非常感谢您对我们的支持!</h3>
+                </div>
+                <div class="text-center col-md-12 col-lg-8">
+                    <a href="#pablo" class="btn btn-twitter-bg twitter-sharrre btn-round" rel="tooltip" title="Tweet!">
+                        <i class="fa fa-twitter"></i> Twitter
+                    </a>
+                    <a href="#pablo" class="btn btn-google-bg linkedin-sharrre btn-round" rel="tooltip" title="Share!">
+                        <i class="fa fa-google-plus"></i> Google
+                    </a>
+                    <a href="#pablo" class="btn btn-facebook-bg facebook-sharrre btn-round" rel="tooltip" title="Share!">
+                        <i class="fa fa-facebook-square"></i> Facebook
+                    </a>
+                    <a href="https://github.com/creativetimofficial/paper-kit" class="btn btn-github-bg btn-github sharrre btn-round" rel="tooltip"
+                       title="Star on Github">
+                        <i class="fa fa-github"></i> Star
+                    </a>
+                </div>
+            </div>
+        </div>
+    </div>
+    <footer class="footer footer-black  footer-white ">
+        <div class="container">
+            <div class="row">
+                <nav class="footer-nav">
+                    <ul>
+                        <li><a href="https://www.minbb.cn/yumin/resume" target="_blank">作者</a></li>
+                        <li><a href="https://www.minbb.cn/blog" target="_blank">博客</a></li>
+                        <li><a href="https://www.creative-tim.com/license" target="_blank">许可</a></li>
+                    </ul>
+                </nav>
+                <div class="credits ml-auto">
+                    <span class="copyright">
+                        ©<script>document.write(new Date().getFullYear())</script>,
+                        made with <i class="fa fa-heart heart"></i> by Wang Yumin
+                    </span>
+                </div>
+            </div>
+        </div>
+    </footer>
+    <!--   Core JS Files   -->
+    <script src="../static/js/core/jquery.min.js" type="text/javascript"></script>
+    <script src="../static/js/core/popper.min.js" type="text/javascript"></script>
+    <script src="../static/js/core/bootstrap.min.js" type="text/javascript"></script>
+    <!--  Plugin for Switches, full documentation here: http://www.jque.re/plugins/version3/bootstrap.switch/ -->
+    <script src="../static/js/plugins/bootstrap-switch.js"></script>
+    <!--  Plugin for the Sliders, full documentation here: http://refreshless.com/nouislider/ -->
+    <script src="../static/js/plugins/nouislider.min.js" type="text/javascript"></script>
+    <!--  Plugin for the DatePicker, full documentation here: https://github.com/uxsolutions/bootstrap-datepicker -->
+    <script src="../static/js/plugins/moment.min.js"></script>
+    <script src="../static/js/plugins/bootstrap-datepicker.js" type="text/javascript"></script>
+    <!-- Control Center for Paper Kit: parallax effects, scripts for the example pages etc -->
+    <script src="../static/js/paper-kit.js?v=2.2.0" type="text/javascript"></script>
+    <!--  Google Maps Plugin    -->
+    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY_HERE"></script>
+    <script>
+        $(document).ready(function () {
+            if ($("#datetimepicker").length != 0) {
+                $('#datetimepicker').datetimepicker({
+                    icons: {
+                        time: "fa fa-clock-o",
+                        date: "fa fa-calendar",
+                        up: "fa fa-chevron-up",
+                        down: "fa fa-chevron-down",
+                        previous: 'fa fa-chevron-left',
+                        next: 'fa fa-chevron-right',
+                        today: 'fa fa-screenshot',
+                        clear: 'fa fa-trash',
+                        close: 'fa fa-remove'
+                    }
+                });
+            }
+
+            function scrollToDownload() {
+                if ($('.section-download').length != 0) {
+                    $("html, body").animate({
+                        scrollTop: $('.section-download').offset().top
+                    }, 1000);
+                }
+            }
+        });
+    </script>
+</body>
+
+</html>

Some files were not shown because too many files changed in this diff