diff --git a/.gitignore b/.gitignore index ed802c6..caceb04 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ target/ .project logs/ ./logs/ -.idea \ No newline at end of file +.idea +*.iml \ No newline at end of file diff --git a/README.md b/README.md index e8966e6..e5c5207 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,18 @@ ## Spring Boot +## [我的blog地址:https://www.timebusker.top/,持续更新.....](https://timebusker.github.io/) + +----------------- + +

:heart::heart::heart:如果觉得我的文章或者代码对您有帮助,可以请我喝杯咖啡哦:heart::heart::heart:

+
+ WXPAY +                    + ALIPAY +
+

:smile::smile::smile:您的支持将鼓励我继续创作...谢谢!:smile::smile::smile:

+ +----------------- + Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。 该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式, @@ -20,42 +34,61 @@ Spring Boot 项目旨在简化创建产品级的 Spring 应用和服务。你可 ### 模块列表 ---- -#### 第一个模块:[..........................................入门程序](https://github.com/timebusker/spring-boot/tree/master/spring-boot-1-QuickStart/) +#### 第一个模块:[....................................入门程序](https://github.com/timebusker/spring-boot/tree/master/spring-boot-1-QuickStart/) -#### 第二个模块:[..........................................完美支持RESTful API](https://github.com/timebusker/spring-boot/tree/master/spring-boot-2-RESTful/) +#### 第二个模块:[....................................完美支持RESTful API](https://github.com/timebusker/spring-boot/tree/master/spring-boot-2-RESTful/) -#### 第三个模块:[..........................................整合多个日志框架:Log4j、Log4j2、Logback](https://github.com/timebusker/spring-boot/tree/master/spring-boot-3-logs/) +#### 第三个模块:[....................................整合多个日志框架:Log4j、Log4j2、Logback](https://github.com/timebusker/spring-boot/tree/master/spring-boot-3-logs/) -#### 第四个模块:[..........................................使用定时任务](https://github.com/timebusker/spring-boot/tree/master/spring-boot-4-Scheduled/) +#### 第四个模块:[....................................使用定时任务](https://github.com/timebusker/spring-boot/tree/master/spring-boot-4-Scheduled/) -#### 第五个模块:[..........................................使用@Async实现异步调用](https://github.com/timebusker/spring-boot/tree/master/spring-boot-5-Async/) +#### 第五个模块:[....................................使用@Async实现异步调用](https://github.com/timebusker/spring-boot/tree/master/spring-boot-5-Async/) -#### 第六个模块:[..........................................统一异常捕获处理](https://github.com/timebusker/spring-boot/tree/master/spring-boot-6-GlobalException/) +#### 第六个模块:[....................................统一异常捕获处理](https://github.com/timebusker/spring-boot/tree/master/spring-boot-6-GlobalException/) -#### 第七个模块:[..........................................集成Ehcache缓存框架](https://github.com/timebusker/spring-boot/tree/master/spring-boot-7-EhCache/) +#### 第七个模块:[....................................集成Ehcache缓存框架](https://github.com/timebusker/spring-boot/tree/master/spring-boot-7-EhCache/) -#### 第八个模块:[..........................................集成AOP面向切面编程](https://github.com/timebusker/spring-boot/tree/master/spring-boot-8-AOP/) +#### 第八个模块:[....................................集成AOP面向切面编程](https://github.com/timebusker/spring-boot/tree/master/spring-boot-8-AOP/) -#### 第九个模块:[..........................................集成JavaMailSender](https://github.com/timebusker/spring-boot/tree/master/spring-boot-9-JavaMailSender/) +#### 第九个模块:[....................................集成JavaMailSender](https://github.com/timebusker/spring-boot/tree/master/spring-boot-9-JavaMailSender/) -#### 第十个模块:[..........................................使用spring-data持久层](https://github.com/timebusker/spring-boot/tree/master/spring-boot-10-SpringData/) +#### 第十个模块:[....................................使用spring-data持久层](https://github.com/timebusker/spring-boot/tree/master/spring-boot-10-SpringData/) -#### 第十一个模块:[......................................集成SpringSecurity安全框架](https://github.com/timebusker/spring-boot/tree/master/spring-boot-11-SpringSecurity/) +#### 第十一个模块:[................................集成SpringSecurity安全框架](https://github.com/timebusker/spring-boot/tree/master/spring-boot-11-SpringSecurity/) -#### 第十二个模块:[......................................集成Swagger2构建强大的RESTful API](https://github.com/timebusker/spring-boot/tree/master/spring-boot-12-Swagger2/) +#### 第十二个模块:[................................集成Swagger2构建强大的RESTful API](https://github.com/timebusker/spring-boot/tree/master/spring-boot-12-Swagger2/) -#### 第十三个模块:[......................................集成MyBatis持久层框架](https://github.com/timebusker/spring-boot/tree/master/spring-boot-13-MyBatis/) +#### 第十三个模块:[................................集成MyBatis持久层框架](https://github.com/timebusker/spring-boot/tree/master/spring-boot-13-MyBatis/) -#### 第十四个模块:[......................................使用spring JdbcTemplate持久层框架](https://github.com/timebusker/spring-boot/tree/spring-boot-14-JdbcTemplate/) +#### 第十四个模块:[................................使用spring JdbcTemplate持久层框架](https://github.com/timebusker/spring-boot/tree/spring-boot-14-JdbcTemplate/) -#### 第十五个模块:[......................................集成Redis中间件项目实践](https://github.com/timebusker/spring-boot/tree/master/spring-boot-15-Redis/) +#### 第十五个模块:[................................集成Redis中间件项目实践](https://github.com/timebusker/spring-boot/tree/master/spring-boot-15-Redis/) -#### 第十六个模块:[......................................使用Transcation保证数据一致性](https://github.com/timebusker/spring-boot/tree/master/spring-boot-16-Transcation/) +#### 第十六个模块:[................................使用Transcation保证数据一致性](https://github.com/timebusker/spring-boot/tree/master/spring-boot-16-Transcation/) -#### 第十七个模块:[......................................应用的健康监控](https://github.com/timebusker/spring-boot/tree/master/spring-boot-17-monitor/) +#### 第十七个模块:[................................应用的健康监控](https://github.com/timebusker/spring-boot/tree/master/spring-boot-17-monitor/) -#### 第十八个模块:[......................................消息队列实践](https://github.com/timebusker/spring-boot/tree/master/spring-boot-18-MQ/) +#### 第十八个模块:[................................消息队列实践](https://github.com/timebusker/spring-boot/tree/master/spring-boot-18-MQ/) -#### 第十九个模块:[......................................Spring Boot自定义Starter](https://github.com/timebusker/spring-boot/tree/master/spring-boot-19-Definition-Starter/) +#### 第十九个模块:[................................Spring Boot自定义Starter](https://github.com/timebusker/spring-boot/tree/master/spring-boot-19-Definition-Starter/) ----- +#### 第二十个模块:[................................Spring Boot结合Freemaker使用](https://github.com/timebusker/spring-boot/tree/master/spring-boot-20-Freemarker/) + +#### 第二十一个模块:[................................Spring Boot多数据源配置使用原理](https://github.com/timebusker/spring-boot/tree/master/spring-boot-21-MultiDataSource/) + +#### 第二十二个模块:[................................Spring Boot基于Vue快速搭建Web管理系统](https://github.com/timebusker/spring-boot/tree/master/spring-boot-22-FarstPlus/) + +#### 第二十三个模块:[................................Spring Boot多种方式连接MongoDB操作](https://github.com/timebusker/spring-boot/tree/master/spring-boot-23-MongoDB/) + +---- + +### 关于Spring Boot模板引擎 +- 虽然现在很多开发,都采用了前后端完全分离的模式,即后端只提供数据接口,前端通过AJAX请求获取数据,完全不需要用的模板引擎。 +这种方式的优点在于前后端完全分离,并且随着近几年前端工程化工具和MVC框架的完善,使得这种模式的维护成本相对来说也更加低一点。 +但是这种模式不利于SEO,并且在性能上也会稍微差一点,还有一些场景,使用模板引擎会更方便,比如说邮件模板。 + +- 总体来讲,Spring boot对thymeleaf和Freemaker支持比较友好,配置相对也简单一点,Spring Boot不建议使用JSP,因为在使用嵌入式servlet容器时,有一些使用限制。 +在实际的开发中,大多也以这两种模板引擎为主,很少有用jsp的,jsp现在可能更多是在实验或者学习阶段使用。 + +![image](https://github.com/timebusker/spring-boot/raw/master/static/111111.png?raw=true) +[性能对比测试](https://github.com/jreijn/spring-comparing-template-engines) diff --git a/_git_pull.cmd b/_git_pull.cmd new file mode 100644 index 0000000..d482665 --- /dev/null +++ b/_git_pull.cmd @@ -0,0 +1,3 @@ +color 0a +@echo off & setlocal +git pull \ No newline at end of file diff --git a/_git_push.cmd b/_git_push.cmd new file mode 100644 index 0000000..1511d7e --- /dev/null +++ b/_git_push.cmd @@ -0,0 +1,11 @@ +color 0a +@echo off & setlocal + +set var=":sun_with_face::sunflower::palm_tree::house_with_garden::office::octocat::guitar::meat_on_bone:" +set d=%date:~0,10% +set t=%time:~0,8% +set m="springboot版本升级到2.1.3" + +git add . +git commit -am "%d% %t% ____ %var% %m%" +git push origin master \ No newline at end of file diff --git a/pom.xml b/pom.xml index 5aab73d..d40c20d 100644 --- a/pom.xml +++ b/pom.xml @@ -12,9 +12,17 @@ org.springframework.boot spring-boot-starter-parent - 1.4.5.RELEASE + 2.1.2.RELEASE + + utf-8 + utf-8 + 1.8 + 1.8 + yyyyMMddHHmmss + + @@ -30,9 +38,8 @@ - - spring-boot + ${project.name}-${maven.build.timestamp} @@ -41,6 +48,7 @@ spring-boot-maven-plugin true + com.timebusker.App @@ -52,9 +60,7 @@ 128m 512m true - 1.3 UTF-8 - -verbose -bootclasspath ${java.home}\lib\rt.jar @@ -79,41 +85,12 @@ spring-boot-17-monitor spring-boot-18-MQ spring-boot-19-Definition-Starter + spring-boot-20-Freemarker + spring-boot-21-MultiDataSource + spring-boot-22-FarstPlus + spring-boot-23-MongoDB + spring-boot-13-MyBatis-XML + spring-boot-24-WebSocket - - - Aliyun_Nexus - Aliyun Nexus Repository - http://maven.aliyun.com/nexus/content/groups/public/ - - true - - - false - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - false - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - true - - - false - - - \ No newline at end of file diff --git a/spring-boot-1-QuickStart/.gitignore b/spring-boot-1-QuickStart/.gitignore index 28972e5..bec3fb0 100644 --- a/spring-boot-1-QuickStart/.gitignore +++ b/spring-boot-1-QuickStart/.gitignore @@ -1,4 +1,5 @@ .settings/ target/ .classpath -.project \ No newline at end of file +.project +*.iml \ No newline at end of file diff --git a/spring-boot-1-QuickStart/pom.xml b/spring-boot-1-QuickStart/pom.xml index 361a559..9a8eeb6 100644 --- a/spring-boot-1-QuickStart/pom.xml +++ b/spring-boot-1-QuickStart/pom.xml @@ -1,68 +1,56 @@ - 4.0.0 - - cn.timebusker - spring-boot - 2.0.0 - - spring-boot-1-QuickStart - spring-boot-1-QuickStart - http://maven.apache.org - - UTF-8 - - - - - - - org.springframework.boot - spring-boot-starter - - - - org.springframework.boot - spring-boot-starter-logging - - - - - - org.springframework.boot - spring-boot-starter-test - test - - - - org.springframework.boot - spring-boot-starter-web - - - - org.springframework.boot - spring-boot-starter-tomcat - - - - - - - org.springframework.boot - spring-boot-starter-jetty - - - - org.springframework.boot - spring-boot-devtools - true - - - - - spring-boot-1-QuickStart - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" + xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + 4.0.0 + + cn.timebusker + spring-boot + 2.0.0 + + spring-boot-1-QuickStart + spring-boot-1-QuickStart + http://maven.apache.org + + UTF-8 + + + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + + org.springframework.boot + spring-boot-starter-jetty + + + + org.springframework.boot + spring-boot-devtools + true + + diff --git a/spring-boot-1-QuickStart/spring-boot-1-QuickStart.iml b/spring-boot-1-QuickStart/spring-boot-1-QuickStart.iml deleted file mode 100644 index a7298bc..0000000 --- a/spring-boot-1-QuickStart/spring-boot-1-QuickStart.iml +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-1-QuickStart/src/main/resources/application.properties b/spring-boot-1-QuickStart/src/main/resources/application.properties index 928dc93..4fd004a 100644 --- a/spring-boot-1-QuickStart/src/main/resources/application.properties +++ b/spring-boot-1-QuickStart/src/main/resources/application.properties @@ -1,29 +1,29 @@ -#Spring Boot 会自动扫描classpath下的application.properties文件,如果有就加载文件配置 +#Spring Boot \u4F1A\u81EA\u52A8\u626B\u63CFclasspath\u4E0B\u7684application.properties\u6587\u4EF6\uFF0C\u5982\u679C\u6709\u5C31\u52A0\u8F7D\u6587\u4EF6\u914D\u7F6E -#自定义属性与加载 cn.timebusker.conf.DefinitionConfig.java +#\u81EA\u5B9A\u4E49\u5C5E\u6027\u4E0E\u52A0\u8F7D cn.timebusker.conf.DefinitionConfig.java cn.timebusker.name=PROGRAMMER -cn.timebusker.title=Spring Boot -#在application.properties中的各个参数之间也可以直接引用来使用 -cn.timebusker.desc=${cn.timebusker.name}is code refactoring << ${cn.timebusker.title} with v1.5.2.RELEASE >> -# 随机字符串 +cn.timebusker.title=Spring Boot--${spring.profiles.active} +#\u5728application.properties\u4E2D\u7684\u5404\u4E2A\u53C2\u6570\u4E4B\u95F4\u4E5F\u53EF\u4EE5\u76F4\u63A5\u5F15\u7528\u6765\u4F7F\u7528 +cn.timebusker.desc=${cn.timebusker.name}is code refactoring << ${cn.timebusker.title} with v1.5.2.RELEASE >> +# \u968F\u673A\u5B57\u7B26\u4E32 cn.timebusker.value=${random.value} -# 随机int +# \u968F\u673Aint cn.timebusker.number=${random.int} -# 随机long +# \u968F\u673Along cn.timebusker.bignumber=${random.long} -# 10以内的随机数 +# 10\u4EE5\u5185\u7684\u968F\u673A\u6570 cn.timebusker.random1=${random.int(10)} -# 10-20的随机数 +# 10-20\u7684\u968F\u673A\u6570 cn.timebusker.random2=${random.int[10,20]} ######################################################################################## -#Spring Boot中多环境配置文件名需要满足application-{profile}.properties的格式 {profile}对应你的环境标识 +#Spring Boot\u4E2D\u591A\u73AF\u5883\u914D\u7F6E\u6587\u4EF6\u540D\u9700\u8981\u6EE1\u8DB3application-{profile}.properties\u7684\u683C\u5F0F {profile}\u5BF9\u5E94\u4F60\u7684\u73AF\u5883\u6807\u8BC6 -#application-dev.properties:开发环境 -#application-test.properties:测试环境 -#application-prod.properties:生产环境 -# 多环境配置文件激活属性---开发、测试、生产 +#application-dev.properties\uFF1A\u5F00\u53D1\u73AF\u5883 +#application-test.properties\uFF1A\u6D4B\u8BD5\u73AF\u5883 +#application-prod.properties\uFF1A\u751F\u4EA7\u73AF\u5883 +# \u591A\u73AF\u5883\u914D\u7F6E\u6587\u4EF6\u6FC0\u6D3B\u5C5E\u6027---\u5F00\u53D1\u3001\u6D4B\u8BD5\u3001\u751F\u4EA7 spring.profiles.active=dev diff --git a/spring-boot-10-SpringData/.gitignore b/spring-boot-10-SpringData/.gitignore index 28972e5..bec3fb0 100644 --- a/spring-boot-10-SpringData/.gitignore +++ b/spring-boot-10-SpringData/.gitignore @@ -1,4 +1,5 @@ .settings/ target/ .classpath -.project \ No newline at end of file +.project +*.iml \ No newline at end of file diff --git a/spring-boot-10-SpringData/pom.xml b/spring-boot-10-SpringData/pom.xml index 3f39f07..a56d1f1 100644 --- a/spring-boot-10-SpringData/pom.xml +++ b/spring-boot-10-SpringData/pom.xml @@ -67,9 +67,21 @@ spring-boot-starter-data-jpa + + + + + + + com.alibaba + easyexcel + 2.1.0-beta4 + + - mysql - mysql-connector-java + org.postgresql + postgresql + 42.2.8 diff --git a/spring-boot-10-SpringData/spring-boot-10-SpringData.iml b/spring-boot-10-SpringData/spring-boot-10-SpringData.iml deleted file mode 100644 index 0e84ab9..0000000 --- a/spring-boot-10-SpringData/spring-boot-10-SpringData.iml +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-10-SpringData/src/main/java/cn/timebusker/model/one2one/User.java b/spring-boot-10-SpringData/src/main/java/cn/timebusker/model/one2one/User.java index 1ec084a..4f45f98 100644 --- a/spring-boot-10-SpringData/src/main/java/cn/timebusker/model/one2one/User.java +++ b/spring-boot-10-SpringData/src/main/java/cn/timebusker/model/one2one/User.java @@ -11,6 +11,7 @@ import javax.persistence.OneToOne; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; + /** * 指明该类是一个实体Bean,可以通过jpa与数据库表建立映射关系 * 每个成员代表数据库字段名称 @@ -24,52 +25,55 @@ @Table(name = "t_user") public class User implements Serializable { - private static final long serialVersionUID = 905654767215634L; + private static final long serialVersionUID = 905654767215634L; + + public User() { + } + + public User(String userName) { + super(); + this.userName = userName; + } + + /** + * @Id:指定表的主键 + * @GeneratedValue:定义了标识字段生成方式 + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer userId; - public User(String userName) { - super(); - this.userName = userName; - } - - /** - * @Id:指定表的主键 - * @GeneratedValue:定义了标识字段生成方式 - */ - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Integer userId; - - /** - * @Column:定义了将成员属性映射到关系表中的字段名称 - */ - @Column(name = "USER_NAME", length = 100) - private String userName; + /** + * @Column:定义了将成员属性映射到关系表中的字段名称 + */ + @Column(name = "USER_NAME", length = 100) + private String userName; - @OneToOne(cascade = CascadeType.PERSIST) - @PrimaryKeyJoinColumn - private Address address; + @OneToOne(cascade = CascadeType.PERSIST) + @PrimaryKeyJoinColumn + private Address address; - public Integer getUserId() { - return userId; - } + public Integer getUserId() { + return userId; + } - public void setUserId(Integer userId) { - this.userId = userId; - } + public void setUserId(Integer userId) { + this.userId = userId; + } - public String getUserName() { - return userName; - } + public String getUserName() { + return userName; + } - public void setUserName(String userName) { - this.userName = userName; - } + public void setUserName(String userName) { + this.userName = userName; + } - public Address getAddress() { - return address; - } + public Address getAddress() { + return address; + } - public void setAddress(Address address) { - this.address = address; - } + public void setAddress(Address address) { + this.address = address; + } } \ No newline at end of file diff --git a/spring-boot-10-SpringData/src/main/java/cn/timebusker/repository/BasicRepository.java b/spring-boot-10-SpringData/src/main/java/cn/timebusker/repository/BasicRepository.java index 2c6dcb0..67497e3 100644 --- a/spring-boot-10-SpringData/src/main/java/cn/timebusker/repository/BasicRepository.java +++ b/spring-boot-10-SpringData/src/main/java/cn/timebusker/repository/BasicRepository.java @@ -3,7 +3,18 @@ import java.io.Serializable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.NoRepositoryBean; -public interface BasicRepository extends JpaRepository{ - -} +/** + * 使用同一接口继承需要标记为@NoRepositoryBean,避免被spring-data-jpa识别为repository接口 + *

+ * 在做项目时创建对象的功能会交给Spring去管理在扫描Repository层包时会扫描到BaseRepository接口 ; + * 所有对象类接口都会继承此接口 为了告诉JPA不要创建对应接口的bean对象 就在类上加注解@NoRepositoryBean + * + * @param + * @param + */ +@NoRepositoryBean +public interface BasicRepository extends JpaRepository { + +} \ No newline at end of file diff --git a/spring-boot-10-SpringData/src/main/java/cn/timebusker/repository/one2one/UserRepository.java b/spring-boot-10-SpringData/src/main/java/cn/timebusker/repository/one2one/UserRepository.java index 26bc425..e764a26 100644 --- a/spring-boot-10-SpringData/src/main/java/cn/timebusker/repository/one2one/UserRepository.java +++ b/spring-boot-10-SpringData/src/main/java/cn/timebusker/repository/one2one/UserRepository.java @@ -2,8 +2,17 @@ import cn.timebusker.model.one2one.User; import cn.timebusker.repository.BasicRepository; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; -public interface UserRepository extends BasicRepository{ +public interface UserRepository extends BasicRepository { - +// @Query("select userId,userName from t_user where userId >=?1") +// Page queryWithPageByParams(Integer userId, Pageable pageable); + + + Page queryByUserIdGreaterThan(Integer userId, Pageable pageable); + + Page findAll(Pageable pageable); } diff --git a/spring-boot-10-SpringData/src/main/java/cn/timebusker/utils/PageWrapper.java b/spring-boot-10-SpringData/src/main/java/cn/timebusker/utils/PageWrapper.java new file mode 100644 index 0000000..b8e84e8 --- /dev/null +++ b/spring-boot-10-SpringData/src/main/java/cn/timebusker/utils/PageWrapper.java @@ -0,0 +1,75 @@ +package cn.timebusker.utils; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; + +import java.util.Optional; + +/** + * @Description:PageWrapper + * @Author:Administrator + * @Date2019/10/30 16:50 + **/ +public class PageWrapper implements Pageable { + + @Override + public int getPageNumber() { + return 0; + } + + @Override + public int getPageSize() { + return 0; + } + + @Override + public long getOffset() { + return 0; + } + + @Override + public Sort getSort() { + return null; + } + + @Override + public Pageable next() { + return null; + } + + @Override + public Pageable previousOrFirst() { + return null; + } + + @Override + public Pageable first() { + return null; + } + + @Override + public boolean hasPrevious() { + return false; + } + + @Override + public boolean isPaged() { + return false; + } + + @Override + public boolean isUnpaged() { + return false; + } + + @Override + public Sort getSortOr(Sort sort) { + return null; + } + + @Override + public Optional toOptional() { + return Optional.empty(); + } +} diff --git a/spring-boot-10-SpringData/src/main/java/cn/timebusker/web/DownloadData.java b/spring-boot-10-SpringData/src/main/java/cn/timebusker/web/DownloadData.java new file mode 100644 index 0000000..0ff882b --- /dev/null +++ b/spring-boot-10-SpringData/src/main/java/cn/timebusker/web/DownloadData.java @@ -0,0 +1,43 @@ +package cn.timebusker.web; + +import java.util.Date; + +import com.alibaba.excel.annotation.ExcelProperty; + +/** + * 基础数据类 + * + * @author Jiaju Zhuang + **/ +public class DownloadData { + @ExcelProperty("字符串标题") + private String string; + @ExcelProperty("日期标题") + private Date date; + @ExcelProperty("数字标题") + private Double doubleData; + + public String getString() { + return string; + } + + public void setString(String string) { + this.string = string; + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public Double getDoubleData() { + return doubleData; + } + + public void setDoubleData(Double doubleData) { + this.doubleData = doubleData; + } +} diff --git a/spring-boot-10-SpringData/src/main/java/cn/timebusker/web/DownloadExcelDataController.java b/spring-boot-10-SpringData/src/main/java/cn/timebusker/web/DownloadExcelDataController.java new file mode 100644 index 0000000..54bafdb --- /dev/null +++ b/spring-boot-10-SpringData/src/main/java/cn/timebusker/web/DownloadExcelDataController.java @@ -0,0 +1,45 @@ +package cn.timebusker.web; + +import com.alibaba.excel.EasyExcel; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * @Description:DownloadExcelDataController + * @Author:Administrator + * @Date2019/10/30 22:43 + **/ +@Controller +public class DownloadExcelDataController { + + @GetMapping("download") + public void download(HttpServletResponse response) throws IOException { + // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman + response.setContentType("application/vnd.ms-excel"); + response.setCharacterEncoding("utf-8"); + // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 + String fileName = URLEncoder.encode("测试", "UTF-8"); + response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); + EasyExcel.write(response.getOutputStream(), DownloadData.class).sheet("模板").doWrite(data()); + } + + private List data() { + List list = new ArrayList(); + for (int i = 0; i < 10000; i++) { + DownloadData data = new DownloadData(); + data.setString("字符串" + 0); + data.setDate(new Date()); + data.setDoubleData(0.56); + list.add(data); + } + return list; + } + +} diff --git a/spring-boot-10-SpringData/src/main/resources/application-dev.properties b/spring-boot-10-SpringData/src/main/resources/application-dev.properties index e8741da..87fa8a9 100644 --- a/spring-boot-10-SpringData/src/main/resources/application-dev.properties +++ b/spring-boot-10-SpringData/src/main/resources/application-dev.properties @@ -1,5 +1,5 @@ # 项目contextPath,一般在正式发布版本中,我们不配置 -server.context-path=/logback +server.servlet.context-path=/data-jpa # 错误页,指定发生错误时,跳转的URL。请查看BasicErrorController源码便知 server.error.path=/error # 服务端口 @@ -10,8 +10,8 @@ server.session-timeout=60 # server.address=192.168.16.11 # 数据库连接 -spring.datasource.url=jdbc:mysql://localhost:3306/timebusker-spring -spring.datasource.username=root -spring.datasource.password=root -spring.datasource.driver-class-name=com.mysql.jdbc.Driver +spring.datasource.url=jdbc:postgresql://12.12.12.6:5432/db_test +spring.datasource.username=postgres +spring.datasource.password=timebusker +spring.datasource.driver-class-name=org.postgresql.Driver spring.jpa.properties.hibernate.hbm2ddl.auto=update \ No newline at end of file diff --git a/spring-boot-10-SpringData/src/test/java/cn/timebusker/test/CommonTest.java b/spring-boot-10-SpringData/src/test/java/cn/timebusker/test/CommonTest.java new file mode 100644 index 0000000..f48271e --- /dev/null +++ b/spring-boot-10-SpringData/src/test/java/cn/timebusker/test/CommonTest.java @@ -0,0 +1,23 @@ +package cn.timebusker.test; + +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +/** + * @Description:CommonTest + * @Author:Administrator + * @Date2019/10/30 20:11 + **/ +public class CommonTest { + + @Test + public void test1() { + Map map = new HashMap<>(); + map.put("1", 1); + + System.out.println(map.get("1")); + System.out.println(map.get("2").toString()); + } +} \ No newline at end of file diff --git a/spring-boot-10-SpringData/src/test/java/cn/timebusker/test/One2oneTest.java b/spring-boot-10-SpringData/src/test/java/cn/timebusker/test/One2oneTest.java index bc82687..c930410 100644 --- a/spring-boot-10-SpringData/src/test/java/cn/timebusker/test/One2oneTest.java +++ b/spring-boot-10-SpringData/src/test/java/cn/timebusker/test/One2oneTest.java @@ -1,49 +1,78 @@ package cn.timebusker.test; -import javax.annotation.Resource; - +import cn.timebusker.App; +import cn.timebusker.model.one2one.Address; +import cn.timebusker.model.one2one.User; +import cn.timebusker.repository.one2one.AddressRepository; +import cn.timebusker.repository.one2one.UserRepository; +import com.alibaba.fastjson.JSON; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; -import cn.timebusker.App; -import cn.timebusker.model.one2one.Address; -import cn.timebusker.model.one2one.User; -import cn.timebusker.repository.one2one.AddressRepository; -import cn.timebusker.repository.one2one.UserRepository; +import javax.annotation.Resource; @RunWith(SpringRunner.class) -@SpringBootTest(classes=App.class) +@SpringBootTest(classes = App.class) @ActiveProfiles("dev") public class One2oneTest { - - @Resource - AddressRepository addressrepo; - - @Resource - UserRepository userrepo; - - /** - * 单独保存user - * success() - */ - @Test - public void test1() throws Exception { - User u = new User("aaa"); - userrepo.save(u); - } - - /** - * 单独保存address - * failure: attempted to assign id from null one-to-one property [cn.timebusker.model.one2one.Address.user] - */ - @Test - public void test2() { - Address address = new Address("一二一大街", "昆明市"); - addressrepo.save(address); - } - - + + @Resource + AddressRepository addressRepository; + + @Resource + UserRepository userRepository; + + /** + * 单独保存user + * success() + */ + @Test + public void test1() throws Exception { + for (int i = 0; i <= 27; i++) { + User user = new User("a_" + System.currentTimeMillis()); + userRepository.save(user); + } + } + + /** + * 分页测试 + */ + @Test + public void test11() { + Pageable pageable = new PageRequest(0, 15, new Sort(Sort.Direction.DESC, "userId")); + Page page = userRepository.findAll(pageable); + System.out.println(JSON.toJSONString(page)); + } + + @Test + public void test12() { + Pageable pageable = new PageRequest(0, 15, new Sort(Sort.Direction.DESC, "userId")); + Page page = userRepository.queryByUserIdGreaterThan(453, pageable); + System.err.println(JSON.toJSONString(page)); + } + + @Test + public void test13() { + Pageable pageable = new PageRequest(1, 15, new Sort(Sort.Direction.DESC, "userId")); + Page page = userRepository.findAll(pageable); + System.err.println(JSON.toJSONString(page)); + } + + + /** + * 单独保存address + * failure: attempted to assign id from null one-to-one property [cn.timebusker.model.one2one.Address.user] + */ + @Test + public void test2() { + Address address = new Address("一二一大街", "昆明市"); + addressRepository.save(address); + } } diff --git a/spring-boot-11-SpringSecurity/.gitignore b/spring-boot-11-SpringSecurity/.gitignore index 28972e5..bec3fb0 100644 --- a/spring-boot-11-SpringSecurity/.gitignore +++ b/spring-boot-11-SpringSecurity/.gitignore @@ -1,4 +1,5 @@ .settings/ target/ .classpath -.project \ No newline at end of file +.project +*.iml \ No newline at end of file diff --git a/spring-boot-11-SpringSecurity/README.md b/spring-boot-11-SpringSecurity/README.md index 77bbf6d..103d554 100644 --- a/spring-boot-11-SpringSecurity/README.md +++ b/spring-boot-11-SpringSecurity/README.md @@ -1,77 +1,672 @@ ---- -## [spring-boot-3-logs-Logback 集成Logback日志框架](https://github.com/timebusker/spring-boot/tree/master/spring-boot-3-logs/spring-boot-3-logs-Logback/) - -### 项目阐述 - ![image](https://github.com/timebusker/spring-boot/raw/master/static/spring-boot-3-logs/spring-boot-3-logs-Logback/Logback.png?raw=true) - - + #### SLF4J+Logback配置说明 - * [logback日志分开纪录](http://www.cnblogs.com/DeepLearing/p/5664941.html)
- * [logback节点配置详解](http://www.cnblogs.com/DeepLearing/p/5663178.html) - * [logback 中文手册.pdf](https://github.com/timebusker/spring-boot/raw/master/static/spring-boot-3-logs/spring-boot-3-logs-Logback/logback_cn.pdf?raw=true) - - + #### 配置多环境不同日志级别 - ***logback.xml*配置讲解** -```xml - - - - - - - - - - - - - - %date [%thread] %-5level %logger{80} || %msg%n - - - - - - - - - - - - - - ${TEST_FILE_PATH} - - - ${TEST_FILE_PATH}/info.%d{yyyy-MM-dd}.log - - 100 - - - ${PATTERN} - - - - - - - - - - - ${PRO_FILE_PATH} - - ${PRO_FILE_PATH}/warn.%d{yyyy-MM-dd}.log - 100 - - - ${PATTERN} - - - - - - - -``` - ----- \ No newline at end of file +### [Spring Security教程系列请移步到这里](https://github.com/timebusker/Spring-Security-In-Action) +## [spring-boot-11-SpringSecurity 集成SpringSecurity安全框架](https://github.com/timebusker/spring-boot/tree/master/spring-boot-11-SpringSecurity) + +### Spring Security 简介 +Spring Security为基于 Java EE 的企业软件应用程序提供全面的安全服务。特别是使用 Spring Framework 构建的项目,可以更好的使用 Spring Security 来加快构建的速度。 +Spring Security 的出现有有很多原因,但主要是基于 Java EE 的 Servlet 规范或 EJB 规范的缺乏对企业应用的安全性方面的支持。而使用 Spring Security 克服了这些问题,并带来了数十个其他有用的可自定义的安全功能。 + +应用程序安全性的两个主要领域是: + - **身份认证(authentication)** :“认证”是建立主体 (principal)的过程。主体 通常是指可以在您的应用程序中执行操作的用户、设备或其他系统; + - **授权(authorization)** :或称为“访问控制(access-control),“授权”是指决定是否允许主体在应用程序中执行操作。为了到达需要授权决定的点,认证过程已经建立了主体的身份。这些概念是常见的,并不是特定于 Spring Security。 + +在认证级别,Spring Security 支持各种各样的认证模型。这些认证模型中的大多数由第三方提供,或者由诸如因特网工程任务组的相关标准机构开发。此外,Spring Security 提供了自己的一组认证功能。具体来说,Spring Security 目前支持所有这些技术的身份验证集成: + + LDAP(一种非常常见的跨平台身份验证需求,特别是在大型环境中 + + 基于表单的身份验证(用于简单的用户界面需求) + + OpenID 身份验证 + + 基于预先建立的请求头的验证(例如Computer Associates Siteminder) + + Jasig Central Authentication Service,也称为CAS,这是一个流行的开源单点登录系统 + + 远程方法调用(RMI)和HttpInvoker(Spring远程协议)的透明认证上下文传播 + + 自动“remember-me”身份验证(所以您可以勾选一个框,以避免在预定时间段内重新验证) + + 匿名身份验证(允许每个未经身份验证的调用,来自动承担特定的安全身份) + + Run-as 身份验证(如果一个调用应使用不同的安全身份继续运行,这是有用的) + + Java认证和授权服务(Java Authentication and Authorization Service,JAAS) + + Java EE 容器认证(因此,如果需要,仍然可以使用容器管理身份验证) + + .................................. + +许多独立软件供应商(ISV)采用Spring Security,是出于这种灵活的认证模型。这样,他们可以快速地将他们的解决方案与他们的最终客户需要进行组合, +从而避免了进行大量的工作或者要求变更。如果上述认证机制都不符合您的需求,Spring Security 作为一个开放平台,可以基于它很容易就实现自己的认证机制。 + +Spring Security提供了一组深入的授权功能。有三个主要领域: + + 对 Web 请求进行授权 + + 授权某个方法是否可以被调用 + + 授权访问单个领域对象实例 + +### Spring Security最小化依赖 +``` + + ...... + + org.springframework.security + spring-security-web + 4.2.2.RELEASE + + + org.springframework.security + spring-security-config + 4.2.2.RELEASE + + ...... + +``` +#### Core - spring-security-core.jar +包含核心的 authentication 和 authorization 的类和接口、远程支持和基础配置API。任何使用 Spring Security 的应用都需要引入这个 jar。支持本地应用、远程客户端、方法级别的安全和 JDBC 用户配置。主要包含的顶级包为为: + - org.springframework.security.core:核心 + - org.springframework.security.access:访问,即 authorization 的作用 + - org.springframework.security.authentication:认证 + - org.springframework.security.provisioning:配置 + +#### Remoting - spring-security-remoting.jar +提供与 Spring Remoting 整合的支持,你并不需要这个除非你需要使用 Spring Remoting 写一个远程客户端。主包为: `org.springframework.security.remoting` + +#### Web - spring-security-web.jar +包含 filter 和相关 Web安全的基础代码。如果我们需要使用 Spring Security 进行 Web 安全认证和基于URL的访问控制。主包为: `org.springframework.security.web` + +##### Config - spring-security-config.jar +包含安全命名空间解析代码和 Java 配置代码。 如果您使用 Spring Security XML 命名空间进行配置或 Spring Security 的 Java 配置支持, +则需要它。 主包为: `org.springframework.security.config`。我们不应该在代码中直接使用这个jar中的类。 + +#### LDAP - spring-security-ldap.jar +LDAP 认证和配置代码。如果你需要进行 LDAP 认证或者管理 LDAP 用户实体。顶级包为: `org.springframework.security.ldap` + +#### ACL - spring-security-acl.jar +特定领域对象的ACL(访问控制列表)实现。使用其可以对特定对象的实例进行一些安全配置。顶级包为: `org.springframework.security.acls` + +#### CAS - spring-security-cas.jar +pring Security CAS 客户端集成。如果你需要使用一个单点登录服务器进行 Spring Security Web 安全认证,需要引入。顶级包为: `org.springframework.security.cas` + +#### OpenID - spring-security-openid.jar +OpenId Web 认证支持。基于一个外部 OpenId 服务器对用户进行验证。顶级包为: `org.springframework.security.openid`,需要使用 OpenID4Java. + +一般情况下,spring-security-core和spring-security-config都会引入,在 Web 开发中,我们通常还会引入spring-security-web。 + +#### 注解 @EnableWebSecurity +在 *Spring boot* 应用中使用 *Spring Security*,用到了 `@EnableWebSecurity`注解,官方说明如下: + +``` +/** + * Add this annotation to an {@code @Configuration} class to have the Spring Security + * configuration defined in any {@link WebSecurityConfigurer} or more likely by extending + * the {@link WebSecurityConfigurerAdapter} base class and overriding individual methods: + */ +``` + +意思是说, 该注解和 `@Configuration` 注解一起使用, 注解 `WebSecurityConfigurer` 类型的类,或者利用`@EnableWebSecurity` +注解继承 `WebSecurityConfigurerAdapter`的类,这样就构成了 *Spring Security* 的配置类。 + +#### 抽象类 WebSecurityConfigurerAdapter +一般情况,会选择继承 `WebSecurityConfigurerAdapter` 类,其官方说明如下: +``` +/** + * Provides a convenient base class for creating a {@link WebSecurityConfigurer} + * instance. The implementation allows customization by overriding methods. + * + *

+ * Will automatically apply the result of looking up + * {@link AbstractHttpConfigurer} from {@link SpringFactoriesLoader} to allow + * developers to extend the defaults. + * To do this, you must create a class that extends AbstractHttpConfigurer and then create a file in the classpath at "META-INF/spring.factories" that looks something like: + *

+ *
+ * org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer = sample.MyClassThatExtendsAbstractHttpConfigurer
+ * 
+ * If you have multiple classes that should be added you can use "," to separate the values. For example: + * + *
+ * org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer = sample.MyClassThatExtendsAbstractHttpConfigurer, sample.OtherThatExtendsAbstractHttpConfigurer
+ * 
+ * + */ +``` +意思是说 `WebSecurityConfigurerAdapter` 提供了一种便利的方式去创建 `WebSecurityConfigurer`的实例, +只需要重写 `WebSecurityConfigurerAdapter` 的方法,即可配置拦截什么URL、设置什么权限等安全控制。 + +#### 方法 configure(AuthenticationManagerBuilder auth) 和 configure(HttpSecurity http) +重写了 `WebSecurityConfigurerAdapter` 的两个方法: + +``` + /** + * 通过 {@link #authenticationManager()} 方法的默认实现尝试获取一个 {@link AuthenticationManager}. + * 如果被复写, 应该使用{@link AuthenticationManagerBuilder} 来指定 {@link AuthenticationManager}. + * + * 例如, 可以使用以下配置在内存中进行注册公开内存的身份验证{@link UserDetailsService}: + * + * // 在内存中添加 user 和 admin 用户 + * @Override + * protected void configure(AuthenticationManagerBuilder auth) { + * auth + * .inMemoryAuthentication().withUser("user").password("password").roles("USER").and() + * .withUser("admin").password("password").roles("USER", "ADMIN"); + * } + * + * // 将 UserDetailsService 显示为 Bean + * @Bean + * @Override + * public UserDetailsService userDetailsServiceBean() throws Exception { + * return super.userDetailsServiceBean(); + * } + * + */ + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + this.disableLocalConfigureAuthenticationBldr = true; + } +``` + +``` + /** + * 复写这个方法来配置 {@link HttpSecurity}. + * 通常,子类不能通过调用 super 来调用此方法,因为它可能会覆盖其配置。 默认配置为: + * + * http.authorizeRequests().anyRequest().authenticated().and().formLogin().and().httpBasic(); + * + */ + protected void configure(HttpSecurity http) throws Exception { + logger.debug("Using default configure(HttpSecurity). If subclassed this will potentially override subclass configure(HttpSecurity)."); + + http + .authorizeRequests() + .anyRequest().authenticated() + .and() + .formLogin().and() + .httpBasic(); + } +``` + +#### final 类 HttpSecurity +表1 HttpSecurity 常用方法及说明 + +| 方法 | 说明 | +| ---- | ---- | +| `openidLogin()` | 用于基于 OpenId 的验证 | +| `headers()`| 将安全标头添加到响应 | +| `cors()` | 配置跨域资源共享( CORS ) | +| `sessionManagement()` | 允许配置会话管理 | +| `portMapper()` | 允许配置一个`PortMapper`(`HttpSecurity#(getSharedObject(class))`),其他提供`SecurityConfigurer`的对象使用 `PortMapper` 从 HTTP 重定向到 HTTPS 或者从 HTTPS 重定向到 HTTP。默认情况下,Spring Security使用一个`PortMapperImpl`映射 HTTP 端口8080到 HTTPS 端口8443,HTTP 端口80到 HTTPS 端口443 | +| `jee()` | 配置基于容器的预认证。 在这种情况下,认证由Servlet容器管理 | +| `x509()` | 配置基于x509的认证 | +| `rememberMe` | 允许配置“记住我”的验证 | +| `authorizeRequests()` | 允许基于使用`HttpServletRequest`限制访问 | +| `requestCache()` | 允许配置请求缓存 | +| `exceptionHandling()` | 允许配置错误处理 | +| `securityContext()` | 在`HttpServletRequests`之间的`SecurityContextHolder`上设置`SecurityContext`的管理。 当使用`WebSecurityConfigurerAdapter`时,这将自动应用 | +| `servletApi()` | 将`HttpServletRequest`方法与在其上找到的值集成到`SecurityContext`中。 当使用`WebSecurityConfigurerAdapter`时,这将自动应用 | +| `csrf()` | 添加 CSRF 支持,使用`WebSecurityConfigurerAdapter`时,默认启用 | +| `logout()` | 添加退出登录支持。当使用`WebSecurityConfigurerAdapter`时,这将自动应用。默认情况是,访问URL"/ logout",使HTTP Session无效来清除用户,清除已配置的任何`#rememberMe()`身份验证,清除`SecurityContextHolder`,然后重定向到"/login?success" | +| `anonymous()` | 允许配置匿名用户的表示方法。 当与`WebSecurityConfigurerAdapter`结合使用时,这将自动应用。 默认情况下,匿名用户将使用`org.springframework.security.authentication.AnonymousAuthenticationToken`表示,并包含角色 "ROLE_ANONYMOUS" | +| `formLogin()` | 指定支持基于表单的身份验证。如果未指定`FormLoginConfigurer#loginPage(String)`,则将生成默认登录页面 | +| `oauth2Login()` | 根据外部OAuth 2.0或OpenID Connect 1.0提供程序配置身份验证 | +| `requiresChannel()` | 配置通道安全。为了使该配置有用,必须提供至少一个到所需信道的映射 | +| `httpBasic()` | 配置 Http Basic 验证 | +| `addFilterAt()` | 在指定的Filter类的位置添加过滤器 | + +#### 类 AuthenticationManagerBuilder + +``` +/** + * {@link SecurityBuilder} used to create an {@link AuthenticationManager}. Allows for + * easily building in memory authentication, LDAP authentication, JDBC based + * authentication, adding {@link UserDetailsService}, and adding + * {@link AuthenticationProvider}'s. + */ +``` +意思是,`AuthenticationManagerBuilder` 用于创建一个 `AuthenticationManager`,让我能够轻松的实现内存验证、LADP验证、基于JDBC的验证、 +添加`UserDetailsService`、添加`AuthenticationProvider`。 + +### Spring Security 校验流程图 +![Spring Security 登录流程.jpg](http://upload-images.jianshu.io/upload_images/3424642-7418a70abdfc7287.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) +#### AbstractAuthenticationProcessingFilter 抽象类 + +``` +/** + * 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。 + * 如果需要验证,则会调用 #attemptAuthentication(HttpServletRequest, HttpServletResponse) 方法。 + * 有三种结果: + * 1、返回一个 Authentication 对象。 + * 配置的 SessionAuthenticationStrategy` 将被调用, + * 然后 然后调用 #successfulAuthentication(HttpServletRequest,HttpServletResponse,FilterChain,Authentication) 方法。 + * 2、验证时发生 AuthenticationException。 + * #unsuccessfulAuthentication(HttpServletRequest, HttpServletResponse, AuthenticationException) 方法将被调用。 + * 3、返回Null,表示身份验证不完整。假设子类做了一些必要的工作(如重定向)来继续处理验证,方法将立即返回。 + * 假设后一个请求将被这种方法接收,其中返回的Authentication对象不为空。 + */ + public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) + throws IOException, ServletException { + + HttpServletRequest request = (HttpServletRequest) req; + HttpServletResponse response = (HttpServletResponse) res; + + if (!requiresAuthentication(request, response)) { + chain.doFilter(request, response); + + return; + } + + if (logger.isDebugEnabled()) { + logger.debug("Request is to process authentication"); + } + + Authentication authResult; + + try { + authResult = attemptAuthentication(request, response); + if (authResult == null) { + // return immediately as subclass has indicated that it hasn't completed + // authentication + return; + } + sessionStrategy.onAuthentication(authResult, request, response); + } + catch (InternalAuthenticationServiceException failed) { + logger.error( + "An internal error occurred while trying to authenticate the user.", + failed); + unsuccessfulAuthentication(request, response, failed); + + return; + } + catch (AuthenticationException failed) { + // Authentication failed + unsuccessfulAuthentication(request, response, failed); + + return; + } + + // Authentication success + if (continueChainBeforeSuccessfulAuthentication) { + chain.doFilter(request, response); + } + + successfulAuthentication(request, response, chain, authResult); + } +``` + +#### UsernamePasswordAuthenticationFilter(AbstractAuthenticationProcessingFilter的子类) +``` +public Authentication attemptAuthentication(HttpServletRequest request, + HttpServletResponse response) throws AuthenticationException { + if (postOnly && !request.getMethod().equals("POST")) { + throw new AuthenticationServiceException( + "Authentication method not supported: " + request.getMethod()); + } + + String username = obtainUsername(request); + String password = obtainPassword(request); + + if (username == null) { + username = ""; + } + + if (password == null) { + password = ""; + } + + username = username.trim(); + + UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken( + username, password); + + // Allow subclasses to set the "details" property + setDetails(request, authRequest); + + return this.getAuthenticationManager().authenticate(authRequest); + } +``` + +`#attemptAuthentication ()` 方法将 request 中的 username 和 password 生成 UsernamePasswordAuthenticationToken 对象,用于 `AuthenticationManager ` 的验证(即 this.getAuthenticationManager().authenticate(authRequest) )。 + +默认情况下注入 Spring 容器的 `AuthenticationManager` 是 `ProviderManager`。 + +#### ProviderManager(AuthenticationManager的实现类) +``` +/** + * 尝试验证 Authentication 对象 + * AuthenticationProvider 列表将被连续尝试,直到 AuthenticationProvider 表示它能够认证传递的过来的Authentication 对象。然后将使用该 AuthenticationProvider 尝试身份验证。 + * 如果有多个 AuthenticationProvider 支持验证传递过来的Authentication 对象,那么由第一个来确定结果,覆盖早期支持AuthenticationProviders 所引发的任何可能的AuthenticationException。 成功验证后,将不会尝试后续的AuthenticationProvider。 + * 如果最后所有的 AuthenticationProviders 都没有成功验证 Authentication 对象,将抛出 AuthenticationException。 + */ + public Authentication authenticate(Authentication authentication) + throws AuthenticationException { + Class toTest = authentication.getClass(); + AuthenticationException lastException = null; + Authentication result = null; + boolean debug = logger.isDebugEnabled(); + + for (AuthenticationProvider provider : getProviders()) { + if (!provider.supports(toTest)) { + continue; + } + + if (debug) { + logger.debug("Authentication attempt using " + + provider.getClass().getName()); + } + + try { + result = provider.authenticate(authentication); + + if (result != null) { + copyDetails(authentication, result); + break; + } + } + catch (AccountStatusException e) { + prepareException(e, authentication); + // SEC-546: Avoid polling additional providers if auth failure is due to + // invalid account status + throw e; + } + catch (InternalAuthenticationServiceException e) { + prepareException(e, authentication); + throw e; + } + catch (AuthenticationException e) { + lastException = e; + } + } + + if (result == null && parent != null) { + // Allow the parent to try. + try { + result = parent.authenticate(authentication); + } + catch (ProviderNotFoundException e) { + // ignore as we will throw below if no other exception occurred prior to + // calling parent and the parent + // may throw ProviderNotFound even though a provider in the child already + // handled the request + } + catch (AuthenticationException e) { + lastException = e; + } + } + + if (result != null) { + if (eraseCredentialsAfterAuthentication + && (result instanceof CredentialsContainer)) { + // Authentication is complete. Remove credentials and other secret data + // from authentication + ((CredentialsContainer) result).eraseCredentials(); + } + + eventPublisher.publishAuthenticationSuccess(result); + return result; + } + + // Parent was null, or didn't authenticate (or throw an exception). + + if (lastException == null) { + lastException = new ProviderNotFoundException(messages.getMessage( + "ProviderManager.providerNotFound", + new Object[] { toTest.getName() }, + "No AuthenticationProvider found for {0}")); + } + + prepareException(lastException, authentication); + + throw lastException; + } +``` +从代码中不难看出,由 provider 来验证 authentication, 核心点方法是: +``` +Authentication result = provider.authenticate(authentication); +``` +此处的 `provider` 是 `AbstractUserDetailsAuthenticationProvider`, +`AbstractUserDetailsAuthenticationProvider` 是AuthenticationProvider的实现,看看它的 `#authenticate(authentication)` 方法: +``` +// 验证 authentication +public Authentication authenticate(Authentication authentication) + throws AuthenticationException { + Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, authentication, + messages.getMessage( + "AbstractUserDetailsAuthenticationProvider.onlySupports", + "Only UsernamePasswordAuthenticationToken is supported")); + + // Determine username + String username = (authentication.getPrincipal() == null) ? "NONE_PROVIDED" + : authentication.getName(); + + boolean cacheWasUsed = true; + UserDetails user = this.userCache.getUserFromCache(username); + + if (user == null) { + cacheWasUsed = false; + + try { + user = retrieveUser(username, + (UsernamePasswordAuthenticationToken) authentication); + } + catch (UsernameNotFoundException notFound) { + logger.debug("User '" + username + "' not found"); + + if (hideUserNotFoundExceptions) { + throw new BadCredentialsException(messages.getMessage( + "AbstractUserDetailsAuthenticationProvider.badCredentials", + "Bad credentials")); + } + else { + throw notFound; + } + } + + Assert.notNull(user, + "retrieveUser returned null - a violation of the interface contract"); + } + + try { + preAuthenticationChecks.check(user); + additionalAuthenticationChecks(user, + (UsernamePasswordAuthenticationToken) authentication); + } + catch (AuthenticationException exception) { + if (cacheWasUsed) { + // There was a problem, so try again after checking + // we're using latest data (i.e. not from the cache) + cacheWasUsed = false; + user = retrieveUser(username, + (UsernamePasswordAuthenticationToken) authentication); + preAuthenticationChecks.check(user); + additionalAuthenticationChecks(user, + (UsernamePasswordAuthenticationToken) authentication); + } + else { + throw exception; + } + } + + postAuthenticationChecks.check(user); + + if (!cacheWasUsed) { + this.userCache.putUserInCache(user); + } + + Object principalToReturn = user; + + if (forcePrincipalAsString) { + principalToReturn = user.getUsername(); + } + + return createSuccessAuthentication(principalToReturn, authentication, user); + } +``` +`AbstractUserDetailsAuthenticationProvider` 内置了缓存机制,从缓存中获取不到的 UserDetails 信息的话,就调用如下方法获取用户信息,然后和 用户传来的信息进行对比来判断是否验证成功。 +``` +// 获取用户信息 +UserDetails user = retrieveUser(username, + (UsernamePasswordAuthenticationToken) authentication); +``` +`#retrieveUser()` 方法在 `DaoAuthenticationProvider` 中实现,`DaoAuthenticationProvider` 是 `AbstractUserDetailsAuthenticationProvider `的子类。具体实现如下: +``` +protected final UserDetails retrieveUser(String username, + UsernamePasswordAuthenticationToken authentication) + throws AuthenticationException { + UserDetails loadedUser; + + try { + loadedUser = this.getUserDetailsService().loadUserByUsername(username); + } + catch (UsernameNotFoundException notFound) { + if (authentication.getCredentials() != null) { + String presentedPassword = authentication.getCredentials().toString(); + passwordEncoder.isPasswordValid(userNotFoundEncodedPassword, + presentedPassword, null); + } + throw notFound; + } + catch (Exception repositoryProblem) { + throw new InternalAuthenticationServiceException( + repositoryProblem.getMessage(), repositoryProblem); + } + + if (loadedUser == null) { + throw new InternalAuthenticationServiceException( + "UserDetailsService returned null, which is an interface contract violation"); + } + return loadedUser; + } +``` +可以看到此处的返回对象 `userDetails` 是由 `UserDetailsService` 的 `#loadUserByUsername(username)` 来获取的。 + +到了此处,就很清晰啦,Demo 中自定义了 `AnyUserDetailsService`。 + +### 实现自定义登录校验 +相比于上一个demo,在 `WebSecurityConfig` 中添加了如下代码: +``` +/** + * 添加 UserDetailsService, 实现自定义登录校验 + */ + @Override + protected void configure(AuthenticationManagerBuilder builder) throws Exception{ + builder.userDetailsService(anyUserDetailsService) + .passwordEncoder(passwordEncoder()); + } + + /** + * 密码加密 + */ + @Bean + public BCryptPasswordEncoder passwordEncoder(){ + return new BCryptPasswordEncoder(); + } + +``` + +> BCryptPasswordEncoder相关知识: + +> 用户表的密码通常使用MD5等不可逆算法加密后存储,为防止彩虹表破解更会先使用一个特定的字符串(如域名)加密,然后再使用一个随机的salt(盐值)加密。 + +> 特定字符串是程序代码中固定的,salt是每个密码单独随机,一般给用户表加一个字段单独存储,比较麻烦。 + +> BCrypt算法将salt随机并混入最终加密后的密码,验证时也无需单独提供之前的salt,从而无需单独处理salt问题。 + +#### BCryptPasswordEncoder 是在哪里使用的? +登录时用到了 `DaoAuthenticationProvider` ,它有一个方法 +`#additionalAuthenticationChecks(UserDetails userDetails, + UsernamePasswordAuthenticationToken authentication)`,此方法用来校验从数据库取得的用户信息和用户输入的信息是否匹配。 + +#### 在注册时,对用户密码加密 +应用 `BCryptPasswordEncoder ` 之后,明文密码是无法被识别的,就会校验失败,只有存入密文密码才能被正常识别。所以,应该在注册时对用户密码进行加密。 +``` +/** + * 加密密码 + */ + private void encryptPassword(UserEntity userEntity){ + String password = userEntity.getPassword(); + password = new BCryptPasswordEncoder().encode(password); + userEntity.setPassword(password); + } +``` + +### 自定义的 `Filter` +Spring Security 默认的过滤器链:[官网位置](http://docs.spring.io/spring-security/site/docs/5.0.0.M1/reference/htmlsingle/#ns-custom-filters) + +|执行顺序|别名|类名称|Namespace Element or Attribute +|--|--|--|--| +|1|CHANNEL_FILTER|ChannelProcessingFilter|http/intercept-url@requires-channel +|2|SECURITY_CONTEXT_FILTER|SecurityContextPersistenceFilter|http +|3|CONCURRENT_SESSION_FILTER|ConcurrentSessionFilter|session-management/concurrency-control +|4|HEADERS_FILTER|HeaderWriterFilter|http/headers +|5|CSRF_FILTER|CsrfFilter|http/csrf +|6|LOGOUT_FILTER|LogoutFilter|http/logout +|7|X509_FILTER|X509AuthenticationFilter|http/x509 +|8|PRE_AUTH_FILTER|AbstractPreAuthenticatedProcessingFilter( Subclasses)|N/A +|9|CAS_FILTER|CasAuthenticationFilter|N/A +|10|FORM_LOGIN_FILTER|UsernamePasswordAuthenticationFilter|http/form-login +|11|BASIC_AUTH_FILTER|BasicAuthenticationFilter|http/http-basic +|12|SERVLET_API_SUPPORT_FILTER|SecurityContextHolderAwareRequestFilter|http/@servlet-api-provision +|13|JAAS_API_SUPPORT_FILTER|JaasApiIntegrationFilter|http/@jaas-api-provision +|14|REMEMBER_ME_FILTER|RememberMeAuthenticationFilter|http/remember-me +|15|ANONYMOUS_FILTER|AnonymousAuthenticationFilter|http/anonymous +|16|SESSION_MANAGEMENT_FILTER|SessionManagementFilter|session-management +|17|EXCEPTION_TRANSLATION_FILTER|ExceptionTranslationFilter|http +|18|FILTER_SECURITY_INTERCEPTOR|FilterSecurityInterceptor|http +|19|SWITCH_USER_FILTER|SwitchUserFilter|N/A + +------- +自定义的 `Filter` 建议继承 `GenericFilterBean`,本文示例: +``` +public class BeforeLoginFilter extends GenericFilterBean { + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + System.out.println("This is a filter before UsernamePasswordAuthenticationFilter."); + // 继续调用 Filter 链 + filterChain.doFilter(servletRequest, servletResponse); + } +} +``` + +配置自定义 Filter 在 Spring Security 过滤器链中的位置 +------ +配置很简单,本文示例: +``` +protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .antMatchers("/").permitAll() + .antMatchers("/user/**").hasRole("USER") + .and() + .formLogin().loginPage("/login").defaultSuccessUrl("/user") + .and() + .logout().logoutUrl("/logout").logoutSuccessUrl("/login"); + + // 在 UsernamePasswordAuthenticationFilter 前添加 BeforeLoginFilter + http.addFilterBefore(new BeforeLoginFilter(), UsernamePasswordAuthenticationFilter.class); + + // 在 CsrfFilter 后添加 AfterCsrfFilter + http.addFilterAfter(new AfterCsrfFilter(), CsrfFilter.class); + } +``` +说明: +`HttpSecurity` 有三个常用方法来配置: + - addFilterBefore(Filter filter, Class beforeFilter) +在 beforeFilter 之前添加 filter + - addFilterAfter(Filter filter, Class afterFilter) +在 afterFilter 之后添加 filter + - addFilterAt(Filter filter, Class atFilter) +在 atFilter 相同位置添加 filter, 此 filter 不覆盖 filter + +> 通过在不同 `Filter` 的 `doFilter()` 方法中加断点调试,可以判断哪个 filter 先执行,从而判断 filter 的执行顺序 。 + + +### [基于URL动态权限n种方案](https://mp.weixin.qq.com/s/Vm9VR-IzHKrVfnpFRax1Hw) + +之前的版本的用户的权限需要使用@PreAuthorize硬编码,那么无法动态的进行权限的配置了,本节基于URL实现动态权限配置方案分析。 + +#### [扩展access()的SpEL表达式](https://mp.weixin.qq.com/s/PX9bXMfZDsobj58sv2jbng) +![Spring Security 登录流程.jpg](/timebusker/timebusker.github.io/master/img/spring-security/7.jpg) + +#### [自定义AccessDecisionManager](https://mp.weixin.qq.com/s/ST8Y3gKPxfvvaRXvflTETA) + +>(1)自定义SecurityMetadataSource,实现从数据库加载ConfigAttribute。 + +>(2) 自定义accessDecisionManager: 进行权限校验。 + +>(3)使用withObjectPostProcessor:自定SecurityMetadataSource和accessDecisionManager。 + +#### [自定义Filter](https://mp.weixin.qq.com/s/f7GoMtaExDHVm0dx8r1AEA) + +> (1)需要提供认证数据规则源数据:通过实现接口FilterInvocationSecurityMetadataSource来进行实现。 + +> (2)自定义accessDecisionManager:进行权限校验。 + +> (3)自定义一个拦截器然后把它添加到springsecurity的filterChain中。 diff --git a/spring-boot-11-SpringSecurity/pom.xml b/spring-boot-11-SpringSecurity/pom.xml index a0ada68..5b887c0 100644 --- a/spring-boot-11-SpringSecurity/pom.xml +++ b/spring-boot-11-SpringSecurity/pom.xml @@ -1,92 +1,139 @@ - 4.0.0 - - cn.timebusker - spring-boot - 2.0.0 - - spring-boot-11-SpringSecurity - spring-boot-11-SpringSecurity - http://maven.apache.org - - UTF-8 - - - - - - org.springframework.boot - spring-boot-starter - - - - org.springframework.boot - spring-boot-starter-logging - - - - - - org.springframework.boot - spring-boot-starter-test - test - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-tomcat - - - - - - - org.springframework.boot - spring-boot-starter-jetty - - - - org.springframework.boot - spring-boot-devtools - true - + 4.0.0 + + cn.timebusker + spring-boot + 2.0.0 + + spring-boot-11-SpringSecurity + spring-boot-11-SpringSecurity + http://maven.apache.org - - - - org.slf4j - slf4j-api - - - org.slf4j - jcl-over-slf4j - - - org.slf4j - log4j-over-slf4j - - - org.slf4j - jul-to-slf4j - - - org.jboss.logging - jboss-logging - - - - ch.qos.logback - logback-classic - - - ch.qos.logback - logback-core - - - + + UTF-8 + + + + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + + org.springframework.boot + spring-boot-starter-jetty + + + + org.springframework.boot + spring-boot-devtools + true + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + mysql + mysql-connector-java + + + + com.alibaba + fastjson + + + + + org.springframework.boot + spring-boot-starter-security + + + + + org.projectlombok + lombok + 1.16.16 + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 1.3.0 + + + + net.sourceforge.nekohtml + nekohtml + 1.9.22 + + + + + + org.slf4j + slf4j-api + + + org.slf4j + jcl-over-slf4j + + + org.slf4j + log4j-over-slf4j + + + org.slf4j + jul-to-slf4j + + + org.jboss.logging + jboss-logging + + + + ch.qos.logback + logback-classic + + + ch.qos.logback + logback-core + + + diff --git a/spring-boot-11-SpringSecurity/spring-boot-11-SpringSecurity.iml b/spring-boot-11-SpringSecurity/spring-boot-11-SpringSecurity.iml deleted file mode 100644 index 2db83f7..0000000 --- a/spring-boot-11-SpringSecurity/spring-boot-11-SpringSecurity.iml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/App.java b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/App.java index 8b1f6c1..80db694 100644 --- a/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/App.java +++ b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/App.java @@ -9,40 +9,7 @@ @SpringBootApplication public class App { - /** - * @SpringBootApplication注解的类一定要放在自定义包下且属于自定义包的 - * - * @SpringBootApplication is a convenience annotation that adds all of the following: - * @SpringBootApplication是一个方便的注解,增加了所有的以下内容: - * - * @Configuration tags the class as a source of bean definitions for the application context. - * @Configuration 标记一个类来作为bean定义的应用程序上下文的资源 - * - * @EnableAutoConfiguration tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings. - * @EnableAutoConfiguration告诉Spring Boot开始加载基于类路径下的配置信息、beans、各种属性配置。 - * - * Normally you would add @EnableWebMvc for a Spring MVC app, but Spring Boot adds - * it automatically when it sees spring-webmvc on the classpath. This flags the application as a web - * application and activates key behaviors such as setting up a DispatcherServlet - * 通常你会添加@EnableWebMvc为Spring MVC的应用程序,但是当Spring Boot在classpath下检索到spring-webmvc时, - * spring boot会自动添加。这标志该应用程序作为Web应用程序,并激活关键行为,如设立的DispatcherServlet - * - * @ComponentScan tells Spring to look for other components, configurations, and services in the the hello package, allowing it to find the HelloController. - * @ComponentScan 告诉Spring寻找其他组件,配置,以及业务层类,最前面才能加载到所有的类。 - */ - - public static void main(String[] args) { - // devtools:是spring boot的一个热部署工具 - //设置 spring.devtools.restart.enabled 属性为false,可以关闭该特性. - //System.setProperty("spring.devtools.restart.enabled","false"); - - // 启动Sprign Boot - ApplicationContext ctx = SpringApplication.run(App.class, args); - System.out.println("Let's inspect the beans provided by Spring Boot:"); - String[] beanNames = ctx.getBeanDefinitionNames(); - Arrays.sort(beanNames); - for (String beanName : beanNames) { - System.out.println(beanName); - } - } + public static void main(String[] args) { + SpringApplication.run(App.class, args); + } } diff --git a/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/mapper/UserMapper.java b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/mapper/UserMapper.java new file mode 100644 index 0000000..8f9f1df --- /dev/null +++ b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/mapper/UserMapper.java @@ -0,0 +1,20 @@ +package cn.timebusker.mapper; + +import cn.timebusker.model.UserEntity; +import org.apache.ibatis.annotations.Insert; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.springframework.stereotype.Component; + +@Mapper +@Component +public interface UserMapper { + + @Insert("insert into tb_user(username, password, nickname, roles) values(#{username}, #{password}, #{nickname}, #{roles})") + int insert(UserEntity userEntity); + + @Select("select * from tb_user where username = #{username}") + UserEntity selectByUsername(@Param("username") String username); + +} diff --git a/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/model/UserEntity.java b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/model/UserEntity.java new file mode 100644 index 0000000..70556ff --- /dev/null +++ b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/model/UserEntity.java @@ -0,0 +1,73 @@ +package cn.timebusker.model; + +import javax.persistence.*; +import java.io.Serializable; + +@Entity +@Table(name = "tb_user") +public class UserEntity implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + /** + * 账号 + */ + private String username; + + /** + * 密码 + */ + private String password; + + /** + * 昵称 + */ + private String nickname; + + /** + * 权限 + */ + private String roles; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public String getRoles() { + return roles; + } + + public void setRoles(String roles) { + this.roles = roles; + } +} diff --git a/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/security/UserDetailsServiceImpl.java b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/security/UserDetailsServiceImpl.java new file mode 100644 index 0000000..b8377d7 --- /dev/null +++ b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/security/UserDetailsServiceImpl.java @@ -0,0 +1,45 @@ +package cn.timebusker.security; + +import cn.timebusker.model.UserEntity; +import cn.timebusker.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.*; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +public class UserDetailsServiceImpl implements UserDetailsService { + + @Autowired + private UserService userService; + + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + UserEntity userEntity = userService.getByUsername(username); + if (userEntity == null) { + throw new UsernameNotFoundException("用户不存在!"); + } + List simpleGrantedAuthorities = createAuthorities(userEntity.getRoles()); + return new User(userEntity.getUsername(), userEntity.getPassword(), simpleGrantedAuthorities); + } + + /** + * 权限字符串转化 + * 如 "USER,ADMIN" -> SimpleGrantedAuthority("USER") + SimpleGrantedAuthority("ADMIN") + * + * @param roleStr 权限字符串 + */ + private List createAuthorities(String roleStr) { + String[] roles = roleStr.split(","); + List simpleGrantedAuthorities = new ArrayList<>(); + for (String role : roles) { + simpleGrantedAuthorities.add(new SimpleGrantedAuthority(role)); + } + return simpleGrantedAuthorities; + } + +} diff --git a/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/security/WebSecurityConfig.java b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/security/WebSecurityConfig.java new file mode 100644 index 0000000..859cb44 --- /dev/null +++ b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/security/WebSecurityConfig.java @@ -0,0 +1,66 @@ +package cn.timebusker.security; + +import cn.timebusker.security.filter.AfterCsrfFilter; +import cn.timebusker.security.filter.BeforeLoginFilter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +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.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.csrf.CsrfFilter; + +@EnableWebSecurity +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private UserDetailsServiceImpl userDetailsServiceImpl; + + /** + * 匹配 "/" 路径,不需要权限即可访问 + * 匹配 "/user" 及其以下所有路径,都需要 "USER" 权限 + * 登录地址为 "/login",登录成功默认跳转到页面 "/user" + * 退出登录的地址为 "/logout",退出成功后跳转到页面 "/login" + * 默认启用 CSRF + */ + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + // 设置白名单 + .antMatchers("/", "/header.html").permitAll() + .antMatchers("/user/**").hasRole("USER") + .and() + .formLogin().loginPage("/login").defaultSuccessUrl("/user") + .and() + .logout().logoutUrl("/logout").logoutSuccessUrl("/login"); + + // 在 UsernamePasswordAuthenticationFilter 前添加 BeforeLoginFilter + http.addFilterBefore(new BeforeLoginFilter(), UsernamePasswordAuthenticationFilter.class); + // 在 CsrfFilter 后添加 AfterCsrfFilter + http.addFilterAfter(new AfterCsrfFilter(), CsrfFilter.class); + } + + /** + * 添加 UserDetailsService, 实现自定义登录校验 + */ + @Override + protected void configure(AuthenticationManagerBuilder builder) throws Exception { + // 自定义校验 + builder.userDetailsService(userDetailsServiceImpl).passwordEncoder(passwordEncoder()); + // 基于内存校验 +// builder.inMemoryAuthentication().withUser("aaa").password("aaa"); +// builder.inMemoryAuthentication().withUser("bbb").password("bbb"); +// builder.inMemoryAuthentication().withUser("ccc").password("ccc"); + } + + /** + * 设置密码加密 + */ + @Bean + public BCryptPasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } +} diff --git a/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/security/constant/RoleConstant.java b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/security/constant/RoleConstant.java new file mode 100644 index 0000000..e3aec7b --- /dev/null +++ b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/security/constant/RoleConstant.java @@ -0,0 +1,6 @@ +package cn.timebusker.security.constant; + +public interface RoleConstant { + + String ROLE_USER = "ROLE_USER"; +} diff --git a/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/security/filter/AfterCsrfFilter.java b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/security/filter/AfterCsrfFilter.java new file mode 100644 index 0000000..8d67a4e --- /dev/null +++ b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/security/filter/AfterCsrfFilter.java @@ -0,0 +1,40 @@ +package cn.timebusker.security.filter; + +import org.springframework.web.filter.GenericFilterBean; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import java.io.IOException; + + +/** + * 抽象类GenericFilterBean实现了javax.servlet.Filter、org.springframework.beans.factory.BeanNameAware、org.springframework.context.EnvironmentAware、org.springframework.web.context.ServletContextAware、org.springframework.beans.factory.InitializingBean和org.springframework.beans.factory.DisposableBean五个接口,作用如下: + *

+ * (1) Filter,实现过滤器; + *

+ * (2) BeanNameAware,实现该接口的setBeanName方法,便于Bean管理器生成Bean; + *

+ * (3) EnvironmentAware,实现该接口的setEnvironment方法,指明该Bean运行的环境; + *

+ * (4) ServletContextAware,实现该接口的setServletContextAware方法,指明上下文; + *

+ * (5) InitializingBean,实现该接口的afterPropertiesSet方法,指明设置属性生的操作; + *

+ * (6) DisposableBean,实现该接口的destroy方法,用于回收资源。 + *

+ * GenericFilterBean的工作流程是:init-doFilter-destory,其中的init和destory在该类中实现,doFilter在具体实现类中实现。 + *

+ * GenericFilterBean中包含一个内部私有类FilterConfigPropertyValues,主要用于将web.xml中定义的init-param的值取出。 + */ +public class AfterCsrfFilter extends GenericFilterBean { + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + System.out.println("This is a filter after CsrfFilter."); + // 继续调用 Filter 链 + filterChain.doFilter(servletRequest, servletResponse); + } + +} diff --git a/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/security/filter/BeforeLoginFilter.java b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/security/filter/BeforeLoginFilter.java new file mode 100644 index 0000000..347fd35 --- /dev/null +++ b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/security/filter/BeforeLoginFilter.java @@ -0,0 +1,38 @@ +package cn.timebusker.security.filter; + +import org.springframework.web.filter.GenericFilterBean; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import java.io.IOException; + +/** + * 抽象类GenericFilterBean实现了javax.servlet.Filter、org.springframework.beans.factory.BeanNameAware、org.springframework.context.EnvironmentAware、org.springframework.web.context.ServletContextAware、org.springframework.beans.factory.InitializingBean和org.springframework.beans.factory.DisposableBean五个接口,作用如下: + *

+ * (1) Filter,实现过滤器; + *

+ * (2) BeanNameAware,实现该接口的setBeanName方法,便于Bean管理器生成Bean; + *

+ * (3) EnvironmentAware,实现该接口的setEnvironment方法,指明该Bean运行的环境; + *

+ * (4) ServletContextAware,实现该接口的setServletContextAware方法,指明上下文; + *

+ * (5) InitializingBean,实现该接口的afterPropertiesSet方法,指明设置属性生的操作; + *

+ * (6) DisposableBean,实现该接口的destroy方法,用于回收资源。 + *

+ * GenericFilterBean的工作流程是:init-doFilter-destory,其中的init和destory在该类中实现,doFilter在具体实现类中实现。 + *

+ * GenericFilterBean中包含一个内部私有类FilterConfigPropertyValues,主要用于将web.xml中定义的init-param的值取出。 + */ +public class BeforeLoginFilter extends GenericFilterBean { + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + System.out.println("This is a filter before UsernamePasswordAuthenticationFilter."); + // 继续调用 Filter 链 + filterChain.doFilter(servletRequest, servletResponse); + } +} diff --git a/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/service/UserService.java b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/service/UserService.java new file mode 100644 index 0000000..9e3c2af --- /dev/null +++ b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/service/UserService.java @@ -0,0 +1,21 @@ +package cn.timebusker.service; + +import cn.timebusker.model.UserEntity; + +public interface UserService { + + /** + * 添加新用户 + * + * username 唯一, 默认 USER 权限 + */ + boolean insert(UserEntity userEntity); + + /** + * 查询用户信息 + * @param username 账号 + * @return UserEntity + */ + UserEntity getByUsername(String username); + +} diff --git a/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/service/impl/BaseUserService.java b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/service/impl/BaseUserService.java new file mode 100644 index 0000000..e847813 --- /dev/null +++ b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/service/impl/BaseUserService.java @@ -0,0 +1,60 @@ +package cn.timebusker.service.impl; + +import cn.timebusker.security.constant.RoleConstant; +import cn.timebusker.mapper.UserMapper; +import cn.timebusker.model.UserEntity; +import cn.timebusker.service.UserService; +import lombok.extern.log4j.Log4j; +import org.springframework.context.annotation.Primary; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.stereotype.Service; + +@Service +@Primary +@Log4j +public class BaseUserService implements UserService { + + private final UserMapper userMapper; + + public BaseUserService(UserMapper userMapper) { + this.userMapper = userMapper; + } + + @Override + public boolean insert(UserEntity userEntity) { + String username = userEntity.getUsername(); + if (exist(username)) { + return false; + } + encryptPassword(userEntity); + userEntity.setRoles(RoleConstant.ROLE_USER); + int result = userMapper.insert(userEntity); + return result == 1; + } + + @Override + public UserEntity getByUsername(String username) { + return userMapper.selectByUsername(username); + } + + /** + * 判断用户是否存在 + * + * @param username 账号 + * @return 密码 + */ + private boolean exist(String username) { + UserEntity userEntity = userMapper.selectByUsername(username); + return (userEntity != null); + } + + /** + * 加密密码 + */ + private void encryptPassword(UserEntity userEntity) { + String password = userEntity.getPassword(); + password = new BCryptPasswordEncoder().encode(password); + userEntity.setPassword(password); + } + +} diff --git a/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/util/LoggingUtil.java b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/util/LoggingUtil.java deleted file mode 100644 index 5f61f30..0000000 --- a/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/util/LoggingUtil.java +++ /dev/null @@ -1,15 +0,0 @@ -package cn.timebusker.util; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class LoggingUtil { - - private final static Logger logger = LoggerFactory.getLogger(LoggingUtil.class); - - public static void creatLogging() { - logger.info("----------------------------------INFO"); - logger.debug("----------------------------------DEBUG"); - logger.error("----------------------------------ERROR"); - } -} diff --git a/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/web/AuthoRoleController.java b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/web/AuthoRoleController.java new file mode 100644 index 0000000..6fc5c58 --- /dev/null +++ b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/web/AuthoRoleController.java @@ -0,0 +1,50 @@ +package cn.timebusker.web; + +import cn.timebusker.model.UserEntity; +import org.springframework.security.access.prepost.*; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * @DESC:AuthoTestController + * @author:timebusker + * @date:2018/7/7 + */ +@RestController +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class AuthoRoleController { + + /** + * 基于方法使用注解,可以结合Spring EL表达式细粒度的权限 + *

+ * 更安全 + */ + + // 基于角色权限校验 + @PreAuthorize("hasRole('ROLE_ADMIN')") + @RequestMapping("/authRole") + public String role() { + return "admin auth"; + } + + // 匹配校验(执行前校验(PreAuthorize),执行后校验(PostAuthorize)) + @PreAuthorize("#id<10 and principal.username.equals(#username) and #user.username.equals('abc')") + @PostAuthorize("returnObject%2==0") + @RequestMapping("/grep") + public Integer test(Integer id, String username, UserEntity user) { + // ... + return id; + } + + @PreFilter("filterObject%2==0") + @PostFilter("filterObject%4==0") + @RequestMapping("/test2") + public List test2(List idList) { + // ... + return idList; + } + +} diff --git a/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/web/HomeController.java b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/web/HomeController.java new file mode 100644 index 0000000..6a8e512 --- /dev/null +++ b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/web/HomeController.java @@ -0,0 +1,41 @@ +package cn.timebusker.web; + +import cn.timebusker.model.UserEntity; +import cn.timebusker.service.UserService; +import lombok.AllArgsConstructor; +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.PostMapping; + +@Controller +@AllArgsConstructor +public class HomeController { + + @Autowired + private UserService userService; + + @GetMapping({"/", "/index", "/home"}) + public String root() { + return "index"; + } + + @GetMapping("/login") + public String login() { + return "login"; + } + + @GetMapping("/register") + public String register() { + return "register"; + } + + @PostMapping("/register") + public String doRegister(UserEntity userEntity) { + // 此处省略校验逻辑 + if (userService.insert(userEntity)) + return "redirect:register?success"; + return "redirect:register?error"; + } + +} diff --git a/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/web/LogsController.java b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/web/LogsController.java deleted file mode 100644 index 31fc456..0000000 --- a/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/web/LogsController.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.timebusker.web; - - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import cn.timebusker.util.LoggingUtil; - - -@RestController -public class LogsController { - - private final static Logger logger = LoggerFactory.getLogger(LogsController.class); - - @RequestMapping(value = { "/**", "/" }, method = RequestMethod.GET) - public Long createLogs() { - logger.info("----------------------------------INFO"); - logger.debug("----------------------------------DEBUG"); - logger.error("----------------------------------ERROR"); - LoggingUtil.creatLogging(); - return System.currentTimeMillis(); - } -} diff --git a/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/web/UserController.java b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/web/UserController.java new file mode 100644 index 0000000..16ef4ed --- /dev/null +++ b/spring-boot-11-SpringSecurity/src/main/java/cn/timebusker/web/UserController.java @@ -0,0 +1,20 @@ +package cn.timebusker.web; + +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; + +import java.security.Principal; + +@Controller +public class UserController { + + @GetMapping("/user") + public String user(@AuthenticationPrincipal Principal principal, Model model){ + model.addAttribute("username", principal.getName()); + return "user/user"; + } + +} diff --git a/spring-boot-11-SpringSecurity/src/main/resources/application-dev.properties b/spring-boot-11-SpringSecurity/src/main/resources/application-dev.properties deleted file mode 100644 index d4eecd1..0000000 --- a/spring-boot-11-SpringSecurity/src/main/resources/application-dev.properties +++ /dev/null @@ -1,10 +0,0 @@ -# 项目contextPath,一般在正式发布版本中,我们不配置 -server.context-path=/logback -# 错误页,指定发生错误时,跳转的URL。请查看BasicErrorController源码便知 -server.error.path=/error -# 服务端口 -server.port=80 -# session最大超时时间(分钟),默认为30 -server.session-timeout=60 -# 该服务绑定IP地址,启动服务器时如本机不是该IP地址则抛出异常启动失败,只有特殊需求的情况下才配置 -# server.address=192.168.16.11 \ No newline at end of file diff --git a/spring-boot-11-SpringSecurity/src/main/resources/application.properties b/spring-boot-11-SpringSecurity/src/main/resources/application.properties index ffb27e2..70cab3a 100644 --- a/spring-boot-11-SpringSecurity/src/main/resources/application.properties +++ b/spring-boot-11-SpringSecurity/src/main/resources/application.properties @@ -1,19 +1,33 @@ -#Spring Boot 会自动扫描classpath下的application.properties文件,如果有就加载文件配置 - - -######################################################################################## -#Spring Boot中多环境配置文件名需要满足application-{profile}.properties的格式 -#{profile}对应你的环境标识 -#application-dev.properties:开发环境 -#application-test.properties:测试环境 -#application-prod.properties:生产环境 -# 多环境配置文件激活属性---开发、测试、生产 -spring.profiles.active=dev - - - - - - - - +server.context-path=/ +server.port=80 + +# Thymeleaf \u7F16\u7801 +# spring.thymeleaf.encoding=UTF-8 +# \u70ED\u90E8\u7F72\u9759\u6001\u6587\u4EF6 +# spring.thymeleaf.cache=false +# \u4F7F\u7528HTML5\u6807\u51C6 +# spring.thymeleaf.mode=HTML5 +# \u4F7F\u7528 H2 \u63A7\u5236\u53F0 +# spring.h2.console.enabled=true +# DataSource +spring.datasource.url=jdbc:mysql://mysql.db.server/test?useSSL=false&serverTimezone=UTC&characterEncoding=utf-8 +spring.datasource.username=root +spring.datasource.password=timebusker +spring.datasource.driver-class-name=com.mysql.jdbc.Driver + +#\u5F00\u542F\u9A7C\u5CF0\u547D\u540D\u8F6C\u6362 +mybatis.configuration.map-underscore-to-camel-case=true + +spring.thymeleaf.prefix=classpath:templates/ +spring.thymeleaf.suffix=.html +spring.thymeleaf.mode=LEGACYHTML5 +spring.thymeleaf.encoding=UTF-8 +spring.thymeleaf.content-type=text/html +spring.thymeleaf.cache=false + + +# JPA +# \u6570\u636E\u65B9\u8A00\u914D\u7F6E +spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect +spring.jpa.show-sql=true +spring.jpa.hibernate.ddl-auto=update diff --git a/spring-boot-11-SpringSecurity/src/main/resources/logback.xml b/spring-boot-11-SpringSecurity/src/main/resources/logback.xml index 9d1b073..35c097b 100644 --- a/spring-boot-11-SpringSecurity/src/main/resources/logback.xml +++ b/spring-boot-11-SpringSecurity/src/main/resources/logback.xml @@ -1,15 +1,13 @@ - - - - - %msg%n - - - - - - - + + + + %msg%n + + + + + + diff --git a/spring-boot-11-SpringSecurity/src/main/resources/templates/header.html b/spring-boot-11-SpringSecurity/src/main/resources/templates/header.html new file mode 100644 index 0000000..e81a611 --- /dev/null +++ b/spring-boot-11-SpringSecurity/src/main/resources/templates/header.html @@ -0,0 +1,35 @@ + + +

+ +
+ + \ No newline at end of file diff --git a/spring-boot-11-SpringSecurity/src/main/resources/templates/index.html b/spring-boot-11-SpringSecurity/src/main/resources/templates/index.html new file mode 100644 index 0000000..229a61e --- /dev/null +++ b/spring-boot-11-SpringSecurity/src/main/resources/templates/index.html @@ -0,0 +1,197 @@ + + + + + timebusker + + + + + + + +
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+ + + + diff --git a/spring-boot-11-SpringSecurity/src/main/resources/templates/login.html b/spring-boot-11-SpringSecurity/src/main/resources/templates/login.html new file mode 100644 index 0000000..8d191f3 --- /dev/null +++ b/spring-boot-11-SpringSecurity/src/main/resources/templates/login.html @@ -0,0 +1,89 @@ + + + + + 登录 | timebusker + + + + +
+ +
+
+ +
+
+
+
+
+

Login

+
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+

登录失败,账号或密码错误!

+
+
+

+
+
+
+ +
+
+
+
+ 创建账号 | 忘记密码? +
+
+
+
+
+
+
+
+ + diff --git a/spring-boot-11-SpringSecurity/src/main/resources/templates/register.html b/spring-boot-11-SpringSecurity/src/main/resources/templates/register.html new file mode 100644 index 0000000..07549e8 --- /dev/null +++ b/spring-boot-11-SpringSecurity/src/main/resources/templates/register.html @@ -0,0 +1,98 @@ + + + + + 注册 | timebusker + + + + +
+ +
+
+ +
+ +
+
+
+
+

Login

+
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+

注册失败,账号已存在!

+
+
+

注册成功,可以登录了!

+
+
+
+ +
+
+ +
+
+
+
+
+ +
+ + + + diff --git a/spring-boot-11-SpringSecurity/src/main/resources/templates/user/no_auth.html b/spring-boot-11-SpringSecurity/src/main/resources/templates/user/no_auth.html new file mode 100644 index 0000000..7bee0db --- /dev/null +++ b/spring-boot-11-SpringSecurity/src/main/resources/templates/user/no_auth.html @@ -0,0 +1,49 @@ + + + + + user | timebusker + + + + +
+ +
+ +
+
+ avatar +
+
+ + diff --git a/spring-boot-11-SpringSecurity/src/main/resources/templates/user/user.html b/spring-boot-11-SpringSecurity/src/main/resources/templates/user/user.html new file mode 100644 index 0000000..4213c17 --- /dev/null +++ b/spring-boot-11-SpringSecurity/src/main/resources/templates/user/user.html @@ -0,0 +1,53 @@ + + + + + user | timebusker + + + + +
+ +
+ +
+
+ avatar +

timebusker

+
+ +
+
+
+ + diff --git a/spring-boot-12-Swagger2/.gitignore b/spring-boot-12-Swagger2/.gitignore index 28972e5..bec3fb0 100644 --- a/spring-boot-12-Swagger2/.gitignore +++ b/spring-boot-12-Swagger2/.gitignore @@ -1,4 +1,5 @@ .settings/ target/ .classpath -.project \ No newline at end of file +.project +*.iml \ No newline at end of file diff --git a/spring-boot-12-Swagger2/spring-boot-12-Swagger2.iml b/spring-boot-12-Swagger2/spring-boot-12-Swagger2.iml deleted file mode 100644 index e2f30c8..0000000 --- a/spring-boot-12-Swagger2/spring-boot-12-Swagger2.iml +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-13-MyBatis-XML/pom.xml b/spring-boot-13-MyBatis-XML/pom.xml new file mode 100644 index 0000000..b3d9ef5 --- /dev/null +++ b/spring-boot-13-MyBatis-XML/pom.xml @@ -0,0 +1,15 @@ + + + + spring-boot + cn.timebusker + 2.0.0 + + 4.0.0 + + spring-boot-13-MyBatis-XML + + + \ No newline at end of file diff --git a/spring-boot-13-MyBatis/.gitignore b/spring-boot-13-MyBatis/.gitignore index 28972e5..bec3fb0 100644 --- a/spring-boot-13-MyBatis/.gitignore +++ b/spring-boot-13-MyBatis/.gitignore @@ -1,4 +1,5 @@ .settings/ target/ .classpath -.project \ No newline at end of file +.project +*.iml \ No newline at end of file diff --git a/spring-boot-13-MyBatis/spring-boot-13-MyBatis.iml b/spring-boot-13-MyBatis/spring-boot-13-MyBatis.iml deleted file mode 100644 index 9c751d0..0000000 --- a/spring-boot-13-MyBatis/spring-boot-13-MyBatis.iml +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-13-MyBatis/src/main/java/cn/timebusker/dao/UserInfoMapper.java b/spring-boot-13-MyBatis/src/main/java/cn/timebusker/dao/UserInfoMapper.java index 1f4574e..c7e4781 100644 --- a/spring-boot-13-MyBatis/src/main/java/cn/timebusker/dao/UserInfoMapper.java +++ b/spring-boot-13-MyBatis/src/main/java/cn/timebusker/dao/UserInfoMapper.java @@ -21,7 +21,7 @@ @Mapper public interface UserInfoMapper { - @Select("SELECT * FROM user_info WHERE username = #{name}") + @Select("SELECT * FROM user_info WHERE username = #{name}") List findByName(@Param("name") String name); @Select("SELECT * FROM user_info WHERE id = #{id}") diff --git a/spring-boot-14-JdbcTemplate/.gitignore b/spring-boot-14-JdbcTemplate/.gitignore index 28972e5..bec3fb0 100644 --- a/spring-boot-14-JdbcTemplate/.gitignore +++ b/spring-boot-14-JdbcTemplate/.gitignore @@ -1,4 +1,5 @@ .settings/ target/ .classpath -.project \ No newline at end of file +.project +*.iml \ No newline at end of file diff --git a/spring-boot-14-JdbcTemplate/spring-boot-14-JdbcTemplate.iml b/spring-boot-14-JdbcTemplate/spring-boot-14-JdbcTemplate.iml deleted file mode 100644 index 2db83f7..0000000 --- a/spring-boot-14-JdbcTemplate/spring-boot-14-JdbcTemplate.iml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-15-Redis/.gitignore b/spring-boot-15-Redis/.gitignore index 28972e5..bec3fb0 100644 --- a/spring-boot-15-Redis/.gitignore +++ b/spring-boot-15-Redis/.gitignore @@ -1,4 +1,5 @@ .settings/ target/ .classpath -.project \ No newline at end of file +.project +*.iml \ No newline at end of file diff --git a/spring-boot-15-Redis/README.md b/spring-boot-15-Redis/README.md index f034cf7..0462929 100644 --- a/spring-boot-15-Redis/README.md +++ b/spring-boot-15-Redis/README.md @@ -10,7 +10,7 @@ - #### [Redis.....................简单使用](https://github.com/timebusker/spring-boot/tree/master/spring-boot-15-Redis/spring-boot-15-Redis-sample/) -- ##### [Redis.....................Cache](https://github.com/timebusker/spring-boot/tree/master/spring-boot-15-Redis/spring-boot-15-Redis-cache) +- #### [Redis.....................Cache](https://github.com/timebusker/spring-boot/tree/master/spring-boot-15-Redis/spring-boot-15-Redis-cache) - #### [Redis.....................Session](https://github.com/timebusker/spring-boot/tree/master/spring-boot-15-Redis/spring-boot-15-Redis-session) diff --git a/spring-boot-15-Redis/pom.xml b/spring-boot-15-Redis/pom.xml index de481e6..2566fab 100644 --- a/spring-boot-15-Redis/pom.xml +++ b/spring-boot-15-Redis/pom.xml @@ -99,9 +99,9 @@ 128m 512m true - 1.3 + 1.8 UTF-8 - -verbose -bootclasspath ${java.home}\lib\rt.jar + diff --git a/spring-boot-15-Redis/spring-boot-15-Redis-cache/.gitignore b/spring-boot-15-Redis/spring-boot-15-Redis-cache/.gitignore new file mode 100644 index 0000000..bec3fb0 --- /dev/null +++ b/spring-boot-15-Redis/spring-boot-15-Redis-cache/.gitignore @@ -0,0 +1,5 @@ +.settings/ +target/ +.classpath +.project +*.iml \ No newline at end of file diff --git a/spring-boot-15-Redis/spring-boot-15-Redis-cache/README.md b/spring-boot-15-Redis/spring-boot-15-Redis-cache/README.md new file mode 100644 index 0000000..3878c23 --- /dev/null +++ b/spring-boot-15-Redis/spring-boot-15-Redis-cache/README.md @@ -0,0 +1,83 @@ +### [Redis使用实践](https://github.com/timebusker/spring-boot/tree/master/spring-boot-15-Redis/spring-boot-15-Redis-cache) + +#### 缓存 +- 缓存就是数据交换的缓冲区(称作Cache),当某一硬件要读取数据时,会首先从缓存中查找需要的数据,如果找到了则直接执行,找不到的话则从内存中找。由于缓存的运行速度比内存快得多, + 故缓存的作用就是帮助硬件更快地运行。 + +- 因为缓存往往使用的是RAM(断电即掉的非永久储存),所以在用完后还是会把文件送到硬盘等存储器里永久存储。电脑里最大的缓存就是内存条了,最快的是CPU上镶的L1和L2缓存,显卡的显存是给显卡运算芯片用的缓存, + 硬盘上也有16M或者32M的缓存。 + +#### Spring Cache + +Spring Cache是作用在方法上的,其核心思想是:当我们在调用一个缓存方法时会把该`方法参数和返回结果作为一个键值对(默认)`存放在缓存中, +等到下次利用同样的参数来调用该方法时将不再执行该方法,而是直接从缓存中获取结果进行返回。 + +##### @CacheConfig —— 统一配置本类的缓存注解的属性 + +`@CacheConfig`是一个类级别的注解,允许在`本类内`共享`缓存的名称、KeyGenerator、CacheManager 和CacheResolver`。 不设置将使用默认值。 + +- cacheNames() default {}; —— 设置缓存名称, +- keyGenerator() default ""; —— 设置缓存的Key值,支持使用spEL表达式嵌入使用方法上的参数。 +- cacheManager() default ""; —— 设置cacheManager +- cacheResolver() default ""; —— 设置cacheResolver + +##### @Cacheable —— 注解在方法上,启用设置缓存 + +启用缓存必须配置缓存名称(`cacheNames`)及该注解中的`value`值,如果使用EHCache,就是ehcache.xml中声明的cache的name。针对类 + +- value :缓存的名称,在`spring`配置文件中定义,必须指定至少一个。例如:`@Cacheable(value=”mycache”)、@Cacheable(value={”cache1”,”cache2”}` + +- key : 缓存的`key,可以为空,如果指定要按照`SpEL`表达式编写,如果不指定,则缺省按照方法的所有参数进行组合`@Cacheable(value=”testcache”,key=”#userName”)` + +- condition : 触发条件,只有满足条件的情况才会加入缓存,默认为空,既表示全部都加入缓存,支持SpEL。`@Cacheable(value=”testcache”,condition=”#userName.length()>2”)` + + +##### @CachePut —— 刷新缓存 + +注释可以确保方法被执行,同时方法的返回值也被录到缓存中,实现缓存与数据库的同步更新spEl表达式 + +- value :缓存的名称,在`spring`配置文件中定义,必须指定至少一个。例如:`@Cacheable(value=”mycache”)、@Cacheable(value={”cache1”,”cache2”}` + +- key : 缓存的`key,可以为空,如果指定要按照`SpEL`表达式编写,如果不指定,则缺省按照方法的所有参数进行组合`@Cacheable(value=”testcache”,key=”#userName”)` + +- condition : 触发条件,只有满足条件的情况才会加入缓存,默认为空,既表示全部都加入缓存,支持SpEL。`@Cacheable(value=”testcache”,condition=”#userName.length()>2”)` + +##### @CacheEvict —— 清空缓存 + +- value : 缓存的名称,在`spring`配置文件中定义,必须指定至少一个。`@CacheEvict(value=”my cache”) + +- key : 缓存的`key`,可以为空,如果指定要按照`SpEL`表达式编写,如果不指定,则缺省按照方法的所有参数进行组合。`@CacheEvict(value=”testcache”,key=”#userName”)` + +- condition : 缓存的条件,可以为空,使用`SpEL`编写,返回`true`或者`false`,只有为`true`才进行缓存。`@CacheEvict(value=”testcache”,condition=”#userName.length()>2”)` + +- allEntries : 是否清空所有缓存内容,缺省为`false`,如果指定为`true`,则方法调用后将立即清空所有缓存。`@CachEvict(value=”testcache”,allEntries=true)` + +- beforeInvocation : 是否在方法执行前就清空,缺省为`false`,如果指定为`true`,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存。 + `@CachEvict(value=”testcache”,beforeInvocation=true)` + +##### @Caching —— 多注解组合使用 +有时候我们可能组合多个Cache注解使用;比如用户新增成功后,我们要添加id–>user;username—>user;email—>user的缓存;此时就需要@Caching组合多个注解标签了。 + +``` +@Caching(put = { +@CachePut(value = "user", key = "#user.id"), +@CachePut(value = "user", key = "#user.username"), +@CachePut(value = "user", key = "#user.email") +}) +public User save(User user) { +``` + +##### 自定义缓存注解 + +``` +@Caching(put = { +@CachePut(value = "user", key = "#user.id"), +@CachePut(value = "user", key = "#user.username"), +@CachePut(value = "user", key = "#user.email") +}) +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface UserSaveCache { +} +``` \ No newline at end of file diff --git a/spring-boot-15-Redis/spring-boot-15-Redis-cache/pom.xml b/spring-boot-15-Redis/spring-boot-15-Redis-cache/pom.xml index 2cd9cf5..2221d01 100644 --- a/spring-boot-15-Redis/spring-boot-15-Redis-cache/pom.xml +++ b/spring-boot-15-Redis/spring-boot-15-Redis-cache/pom.xml @@ -13,6 +13,12 @@ UTF-8 + + + + org.springframework.boot + spring-boot-starter-data-redis + diff --git a/spring-boot-15-Redis/spring-boot-15-Redis-cache/spring-boot-15-Redis-cache.iml b/spring-boot-15-Redis/spring-boot-15-Redis-cache/spring-boot-15-Redis-cache.iml deleted file mode 100644 index a155885..0000000 --- a/spring-boot-15-Redis/spring-boot-15-Redis-cache/spring-boot-15-Redis-cache.iml +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-15-Redis/spring-boot-15-Redis-cache/src/main/java/cn/timebusker/conf/RedisConfig.java b/spring-boot-15-Redis/spring-boot-15-Redis-cache/src/main/java/cn/timebusker/conf/RedisConfig.java new file mode 100644 index 0000000..f7adcd0 --- /dev/null +++ b/spring-boot-15-Redis/spring-boot-15-Redis-cache/src/main/java/cn/timebusker/conf/RedisConfig.java @@ -0,0 +1,88 @@ +package cn.timebusker.conf; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.CachingConfigurerSupport; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cache.interceptor.KeyGenerator; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.cache.RedisCacheManager; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; + +/** + * @DESC:RedisConfig:Redis缓存配置类 + * @author:timebusker + * @date:2019/4/1 + */ + +@Configuration +@EnableCaching +public class RedisConfig extends CachingConfigurerSupport { + + /** + * 缓存管理器 + * @param redisTemplate + * @return + */ + @Bean + public CacheManager cacheManager(RedisTemplate redisTemplate) { + RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate); + //设置缓存过期时间 + cacheManager.setDefaultExpiration(10000); + return cacheManager; + } + + /** + * 设置序列化工具 + * @param factory + * @return + */ + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory factory){ + StringRedisTemplate template = new StringRedisTemplate(factory); + setSerializer(template); + template.afterPropertiesSet(); + return template; + } + + /** + * 缓存数据时value序列化策略 + * @param template + */ + private void setSerializer(StringRedisTemplate template){ + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); + ObjectMapper om = new ObjectMapper(); + om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + jackson2JsonRedisSerializer.setObjectMapper(om); + template.setValueSerializer(jackson2JsonRedisSerializer); + } + + /** + * 自定义缓存key生成策略 + * @return + */ + @Bean + public KeyGenerator keyGenerator() { + return new KeyGenerator() { + @Override + public Object generate(Object target, java.lang.reflect.Method method, Object... params) { + StringBuffer sb = new StringBuffer(); + sb.append(target.getClass().getName()); +// sb.append(method.getName()); +// for (Object obj : params) { +// sb.append(obj.toString()); +// } + sb.append("------->"); + return sb.toString(); + } + }; + } +} diff --git a/spring-boot-15-Redis/spring-boot-15-Redis-cache/src/main/java/cn/timebusker/mapper/UserMapper.java b/spring-boot-15-Redis/spring-boot-15-Redis-cache/src/main/java/cn/timebusker/mapper/UserMapper.java new file mode 100644 index 0000000..cc4c870 --- /dev/null +++ b/spring-boot-15-Redis/spring-boot-15-Redis-cache/src/main/java/cn/timebusker/mapper/UserMapper.java @@ -0,0 +1,65 @@ +package cn.timebusker.mapper; + +import cn.timebusker.model.UserEntity; +import com.alibaba.fastjson.JSON; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Repository; + +import java.util.*; + +/** + * @DESC:UserMapper:模拟数据库操作接口 + * @author:timebusker + * @date:2019/4/1 + */ +@Repository +public class UserMapper { + + private static final Logger logger = LoggerFactory.getLogger(UserMapper.class); + + private final static List users = new ArrayList<>(); + + public List queryUsers() { + logger.info("--------------数据操作----------------"); + synchronized (users) { + return users; + } + } + + public List addUser(UserEntity user) { + logger.info("--------------数据操作----------------"); + synchronized (users) { + users.add(user); + } + return users; + } + + public List deleteUsers(UserEntity user) { + logger.info("--------------数据操作----------------"); + synchronized (users) { + users.remove(user); + } + return users; + } + + public List updateUser(UserEntity user) { + logger.info("--------------数据操作----------------"); + synchronized (users) { + users.remove(user); + users.add(user); + } + return users; + } + + public static void main(String[] args) { + UserMapper mapper = new UserMapper(); + mapper.addUser(new UserEntity(1l, "a", 1, new Date())); + mapper.addUser(new UserEntity(2l, "b", 2, new Date())); + System.out.println(JSON.toJSONString(users)); + mapper.deleteUsers(new UserEntity(2l, "b", 2, new Date())); + System.out.println(JSON.toJSONString(users)); + mapper.updateUser(new UserEntity(2l, "d", 2, new Date())); + System.out.println(JSON.toJSONString(users)); + } +} diff --git a/spring-boot-15-Redis/spring-boot-15-Redis-cache/src/main/java/cn/timebusker/model/UserEntity.java b/spring-boot-15-Redis/spring-boot-15-Redis-cache/src/main/java/cn/timebusker/model/UserEntity.java new file mode 100644 index 0000000..bfad9fe --- /dev/null +++ b/spring-boot-15-Redis/spring-boot-15-Redis-cache/src/main/java/cn/timebusker/model/UserEntity.java @@ -0,0 +1,95 @@ +package cn.timebusker.model; + +import com.alibaba.fastjson.JSON; + +import java.io.Serializable; +import java.util.Date; + +/** + * @DESC:UserEntity:人员信息实体类: + * + * 要缓存的 Java 对象必须实现 Serializable 接口,因为 Spring 会将对象先序列化再存入 Redis,不实现 Serializable 的话将会遇到类似这种错误: + * nested exception is java.lang.IllegalArgumentException + * + * 实现Comparable接口可以完成集合排序功能 + * + * @author:timebusker + * @date:2019/4/1 + */ +public class UserEntity implements Serializable, Comparable { + + private long id; + private String name; + private int age; + private Date createTime; + + /** + * 重写equals对象方法,用于判断对象是否相等(list 中使用 remove时有用) + * + * @param obj + * @return + */ + @Override + public boolean equals(Object obj) { + UserEntity user = (UserEntity) obj; + System.err.println("相等运算:\t" + JSON.toJSONString(this)); + System.err.println("相等运算:\t" + JSON.toJSONString(user)); + return this.id == user.getId(); + } + + @Override + public int compareTo(Object obj) { + UserEntity user = (UserEntity) obj; + System.err.println("比较运算:\t" + JSON.toJSONString(this)); + System.err.println("比较运算:\t" + JSON.toJSONString(user)); + if (this.id > user.getId()) { + return 0; + } else if ((this.id == user.getId()) && user.createTime.compareTo(this.createTime) > 0) { + return 0; + } else { + return 1; + } + } + + public UserEntity() { + } + + public UserEntity(long id, String name, int age, Date createTime) { + this.id = id; + this.name = name; + this.age = age; + this.createTime = createTime; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } +} diff --git a/spring-boot-15-Redis/spring-boot-15-Redis-cache/src/main/java/cn/timebusker/service/UserService.java b/spring-boot-15-Redis/spring-boot-15-Redis-cache/src/main/java/cn/timebusker/service/UserService.java new file mode 100644 index 0000000..737c0e5 --- /dev/null +++ b/spring-boot-15-Redis/spring-boot-15-Redis-cache/src/main/java/cn/timebusker/service/UserService.java @@ -0,0 +1,42 @@ +package cn.timebusker.service; + +import cn.timebusker.mapper.UserMapper; +import cn.timebusker.model.UserEntity; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.*; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @DESC:UserService:用户操作业务类 + * @author:timebusker + * @date:2019/4/1 + */ +@Service +@CacheConfig(cacheNames = "users") +public class UserService { + + @Autowired + private UserMapper mapper; + + @Cacheable() + public List getList() { + return mapper.queryUsers(); + } + + @CachePut() + public List addUser(UserEntity user) { + return mapper.addUser(user); + } + + @CacheEvict(allEntries = true) + public List deleteUser(UserEntity user) { + return mapper.deleteUsers(user); + } + + @CachePut() + public List updateUser(UserEntity user) { + return mapper.updateUser(user); + } +} diff --git a/spring-boot-15-Redis/spring-boot-15-Redis-cache/src/main/java/cn/timebusker/web/indexController.java b/spring-boot-15-Redis/spring-boot-15-Redis-cache/src/main/java/cn/timebusker/web/indexController.java index 6368e2b..cca5a21 100644 --- a/spring-boot-15-Redis/spring-boot-15-Redis-cache/src/main/java/cn/timebusker/web/indexController.java +++ b/spring-boot-15-Redis/spring-boot-15-Redis-cache/src/main/java/cn/timebusker/web/indexController.java @@ -1,19 +1,55 @@ package cn.timebusker.web; +import cn.timebusker.model.UserEntity; +import cn.timebusker.service.UserService; +import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.*; @RestController public class indexController { - private final static Logger logger = LoggerFactory.getLogger(indexController.class); + private final static Logger logger = LoggerFactory.getLogger(indexController.class); + + @Autowired + private UserService service; + + @RequestMapping(value = {"/list"}, method = RequestMethod.GET) + public Object list() { + List list = new ArrayList<>(); + list = service.getList(); + Collections.sort(list); + return list; + } + + @RequestMapping(value = {"/add/{id}"}, method = RequestMethod.GET) + public Object add(@PathVariable("id") long id) { + UserEntity user = new UserEntity(id, id + "", Integer.valueOf(id + ""), new Date()); + List list = new ArrayList<>(); + list = service.addUser(user); + Collections.sort(list); + return list; + } + + @RequestMapping(value = {"/update/{id}"}, method = RequestMethod.GET) + public Object update(@PathVariable("id") long id) { + UserEntity user = new UserEntity(id, id + "", Integer.valueOf(id + ""), new Date()); + List list = new ArrayList<>(); + list = service.updateUser(user); + Collections.sort(list); + return list; + } - @RequestMapping(value = { "/**", "/" }, method = RequestMethod.GET) - public Long createLogs() { - logger.info("----------------------------------INFO"); - return System.currentTimeMillis(); - } + @RequestMapping(value = {"/delete/{id}"}, method = RequestMethod.GET) + public Object delete(@PathVariable("id") long id) { + UserEntity user = new UserEntity(id, id + "", Integer.valueOf(id + ""), new Date()); + List list = new ArrayList<>(); + list = service.deleteUser(user); + Collections.sort(list); + return list; + } } diff --git a/spring-boot-15-Redis/spring-boot-15-Redis-cache/src/main/resources/application-dev.properties b/spring-boot-15-Redis/spring-boot-15-Redis-cache/src/main/resources/application-dev.properties index 8ca4a30..45763cd 100644 --- a/spring-boot-15-Redis/spring-boot-15-Redis-cache/src/main/resources/application-dev.properties +++ b/spring-boot-15-Redis/spring-boot-15-Redis-cache/src/main/resources/application-dev.properties @@ -1,36 +1,29 @@ -# 项目contextPath,一般在正式发布版本中,我们不配置 +# \u9879\u76EEcontextPath\uFF0C\u4E00\u822C\u5728\u6B63\u5F0F\u53D1\u5E03\u7248\u672C\u4E2D\uFF0C\u6211\u4EEC\u4E0D\u914D\u7F6E # server.context-path=/mq -# 错误页,指定发生错误时,跳转的URL。请查看BasicErrorController源码便知 +# \u9519\u8BEF\u9875\uFF0C\u6307\u5B9A\u53D1\u751F\u9519\u8BEF\u65F6\uFF0C\u8DF3\u8F6C\u7684URL\u3002\u8BF7\u67E5\u770BBasicErrorController\u6E90\u7801\u4FBF\u77E5 server.error.path=/error -# 服务端口 +# \u670D\u52A1\u7AEF\u53E3 server.port=80 -# session最大超时时间(分钟),默认为30 +# session\u6700\u5927\u8D85\u65F6\u65F6\u95F4(\u5206\u949F)\uFF0C\u9ED8\u8BA4\u4E3A30 server.session-timeout=60 -# 该服务绑定IP地址,启动服务器时如本机不是该IP地址则抛出异常启动失败,只有特殊需求的情况下才配置 +# \u8BE5\u670D\u52A1\u7ED1\u5B9AIP\u5730\u5740\uFF0C\u542F\u52A8\u670D\u52A1\u5668\u65F6\u5982\u672C\u673A\u4E0D\u662F\u8BE5IP\u5730\u5740\u5219\u629B\u51FA\u5F02\u5E38\u542F\u52A8\u5931\u8D25\uFF0C\u53EA\u6709\u7279\u6B8A\u9700\u6C42\u7684\u60C5\u51B5\u4E0B\u624D\u914D\u7F6E # server.address=192.168.16.11 -# ACTIVEMQ -# 配置消息模型为pub/sub方式:true是Topic;如果是false或者默认,则是queue -spring.jms.pub-sub-domain=true -# URL of the ActiveMQ broker. Auto-generated by default. For instance `tcp://localhost:61616` -# spring.activemq.broker-url= -# Specify if the default broker URL should be in memory. Ignored if an explicit broker has been specified. -# spring.activemq.in-memory=true -# Login password of the broker. -# spring.activemq.password= -# Login user of the broker. -# spring.activemq.user= -# Trust all packages. -# spring.activemq.packages.trust-all=false -# Comma-separated list of specific packages to trust (when not trusting all packages). -# spring.activemq.packages.trusted= -# See PooledConnectionFactory. -# spring.activemq.pool.configuration.*= -# Whether a PooledConnectionFactory should be created instead of a regular ConnectionFactory. -# spring.activemq.pool.enabled=false -# Connection expiration timeout in milliseconds. -# spring.activemq.pool.expiry-timeout=0 -# Connection idle timeout in milliseconds. -# spring.activemq.pool.idle-timeout=30000 -# Maximum number of pooled connections. -# spring.activemq.pool.max-connections=1 \ No newline at end of file +# Redis\u6570\u636E\u5E93\u7D22\u5F15\uFF08\u9ED8\u8BA4\u4E3A0\uFF09 +spring.redis.database=0 +# Redis\u670D\u52A1\u5668\u5730\u5740 +spring.redis.host=12.12.12.3 +# Redis\u670D\u52A1\u5668\u8FDE\u63A5\u7AEF\u53E3 +spring.redis.port=6379 +# Redis\u670D\u52A1\u5668\u8FDE\u63A5\u5BC6\u7801\uFF08\u9ED8\u8BA4\u4E3A\u7A7A\uFF09 +spring.redis.password=C50A16CB99FD1F8DBA0D766713F76937 +# \u8FDE\u63A5\u6C60\u6700\u5927\u8FDE\u63A5\u6570\uFF08\u4F7F\u7528\u8D1F\u503C\u8868\u793A\u6CA1\u6709\u9650\u5236\uFF09 +spring.redis.pool.max-active=8 +# \u8FDE\u63A5\u6C60\u6700\u5927\u963B\u585E\u7B49\u5F85\u65F6\u95F4\uFF08\u4F7F\u7528\u8D1F\u503C\u8868\u793A\u6CA1\u6709\u9650\u5236\uFF09 +spring.redis.pool.max-wait=-1 +# \u8FDE\u63A5\u6C60\u4E2D\u7684\u6700\u5927\u7A7A\u95F2\u8FDE\u63A5 +spring.redis.pool.max-idle=8 +# \u8FDE\u63A5\u6C60\u4E2D\u7684\u6700\u5C0F\u7A7A\u95F2\u8FDE\u63A5 +spring.redis.pool.min-idle=0 +# \u8FDE\u63A5\u8D85\u65F6\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09 +spring.redis.timeout=0 \ No newline at end of file diff --git a/spring-boot-15-Redis/spring-boot-15-Redis-mq/.gitignore b/spring-boot-15-Redis/spring-boot-15-Redis-mq/.gitignore new file mode 100644 index 0000000..bec3fb0 --- /dev/null +++ b/spring-boot-15-Redis/spring-boot-15-Redis-mq/.gitignore @@ -0,0 +1,5 @@ +.settings/ +target/ +.classpath +.project +*.iml \ No newline at end of file diff --git a/spring-boot-15-Redis/spring-boot-15-Redis-mq/spring-boot-15-Redis-mq.iml b/spring-boot-15-Redis/spring-boot-15-Redis-mq/spring-boot-15-Redis-mq.iml deleted file mode 100644 index a155885..0000000 --- a/spring-boot-15-Redis/spring-boot-15-Redis-mq/spring-boot-15-Redis-mq.iml +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-15-Redis/spring-boot-15-Redis-sample/.gitignore b/spring-boot-15-Redis/spring-boot-15-Redis-sample/.gitignore new file mode 100644 index 0000000..bec3fb0 --- /dev/null +++ b/spring-boot-15-Redis/spring-boot-15-Redis-sample/.gitignore @@ -0,0 +1,5 @@ +.settings/ +target/ +.classpath +.project +*.iml \ No newline at end of file diff --git a/spring-boot-15-Redis/spring-boot-15-Redis-sample/pom.xml b/spring-boot-15-Redis/spring-boot-15-Redis-sample/pom.xml index 028cecd..014dccf 100644 --- a/spring-boot-15-Redis/spring-boot-15-Redis-sample/pom.xml +++ b/spring-boot-15-Redis/spring-boot-15-Redis-sample/pom.xml @@ -15,7 +15,7 @@ org.springframework.boot - spring-boot-starter-redis + spring-boot-starter-data-redis diff --git a/spring-boot-15-Redis/spring-boot-15-Redis-sample/spring-boot-15-Redis-sample.iml b/spring-boot-15-Redis/spring-boot-15-Redis-sample/spring-boot-15-Redis-sample.iml deleted file mode 100644 index 0454378..0000000 --- a/spring-boot-15-Redis/spring-boot-15-Redis-sample/spring-boot-15-Redis-sample.iml +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-15-Redis/spring-boot-15-Redis-sample/src/main/java/cn/timebusker/configuration/RedisConfiguration.java b/spring-boot-15-Redis/spring-boot-15-Redis-sample/src/main/java/cn/timebusker/configuration/RedisConfiguration.java index 7203f7d..30e02a7 100644 --- a/spring-boot-15-Redis/spring-boot-15-Redis-sample/src/main/java/cn/timebusker/configuration/RedisConfiguration.java +++ b/spring-boot-15-Redis/spring-boot-15-Redis-sample/src/main/java/cn/timebusker/configuration/RedisConfiguration.java @@ -1,68 +1,66 @@ -package cn.timebusker.configuration; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.redis.connection.RedisConnectionFactory; -import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; -import org.springframework.data.redis.core.RedisTemplate; - -import redis.clients.jedis.JedisPoolConfig; - -@Configuration -public class RedisConfiguration { - - @Value("${spring.redis.database}") - private int dateBase; - @Value("${spring.redis.host}") - private String host; - @Value("${spring.redis.port}") - private int port; - @Value("${spring.redis.password}") - private String password; - @Value("${spring.redis.pool.max-active}") - private int maxTotal; - @Value("${spring.redis.pool.max-wait}") - private int maxWait; - @Value("${spring.redis.pool.max-idle}") - private int maxIdle; - @Value("${spring.redis.pool.min-idle}") - private int minIdle; - @Value("${spring.redis.timeout}") - private int timeout; - - @Bean - JedisConnectionFactory jedisConnectionFactory() { - JedisConnectionFactory factory = new JedisConnectionFactory(); - factory.setDatabase(dateBase); - factory.setHostName(host); - factory.setPort(port); - factory.setPassword(password); - JedisPoolConfig poolConfig = new JedisPoolConfig(); - poolConfig.setMaxIdle(maxIdle); - poolConfig.setMinIdle(minIdle); - poolConfig.setMaxWaitMillis(maxWait); - poolConfig.setMaxTotal(maxTotal); - factory.setPoolConfig(poolConfig); - factory.setTimeout(timeout); - return factory; - } - - /** - * RedisTemplate配置 - * - * @param factory - * @return - */ - @Bean - public RedisTemplate redisTemplate(RedisConnectionFactory factory) { - RedisTemplate template = new RedisTemplate(); - template.setConnectionFactory(factory); -// template.setKeySerializer(new StringRedisSerializer()); -// template.setValueSerializer(new JdkSerializationRedisSerializer()); -// template.setValueSerializer(new RedisObjectSerializer()); -// template.afterPropertiesSet(); - return template; - } - -} \ No newline at end of file +//package cn.timebusker.configuration; +// +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.context.annotation.Bean; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.data.redis.connection.RedisConnectionFactory; +//import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; +//import org.springframework.data.redis.core.RedisTemplate; +// +//@Configuration +//public class RedisConfiguration { +// +// @Value("${spring.redis.database}") +// private int dateBase; +// @Value("${spring.redis.host}") +// private String host; +// @Value("${spring.redis.port}") +// private int port; +// @Value("${spring.redis.password}") +// private String password; +// @Value("${spring.redis.pool.max-active}") +// private int maxTotal; +// @Value("${spring.redis.pool.max-wait}") +// private int maxWait; +// @Value("${spring.redis.pool.max-idle}") +// private int maxIdle; +// @Value("${spring.redis.pool.min-idle}") +// private int minIdle; +// @Value("${spring.redis.timeout}") +// private int timeout; +// +// @Bean +// JedisConnectionFactory jedisConnectionFactory() { +// JedisConnectionFactory factory = new JedisConnectionFactory(); +// factory.setDatabase(dateBase); +// factory.setHostName(host); +// factory.setPort(port); +// factory.setPassword(password); +// JedisPoolConfig poolConfig = new JedisPoolConfig(); +// poolConfig.setMaxIdle(maxIdle); +// poolConfig.setMinIdle(minIdle); +// poolConfig.setMaxWaitMillis(maxWait); +// poolConfig.setMaxTotal(maxTotal); +// factory.setPoolConfig(poolConfig); +// factory.setTimeout(timeout); +// return factory; +// } +// +// /** +// * RedisTemplate配置 +// * +// * @param factory +// * @return +// */ +// @Bean +// public RedisTemplate redisTemplate(RedisConnectionFactory factory) { +// RedisTemplate template = new RedisTemplate(); +// template.setConnectionFactory(factory); +//// template.setKeySerializer(new StringRedisSerializer()); +//// template.setValueSerializer(new JdkSerializationRedisSerializer()); +//// template.setValueSerializer(new RedisObjectSerializer()); +//// template.afterPropertiesSet(); +// return template; +// } +// +//} \ No newline at end of file diff --git a/spring-boot-15-Redis/spring-boot-15-Redis.iml b/spring-boot-15-Redis/spring-boot-15-Redis.iml deleted file mode 100644 index d8f3fc8..0000000 --- a/spring-boot-15-Redis/spring-boot-15-Redis.iml +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-16-Transcation/.gitignore b/spring-boot-16-Transcation/.gitignore index 28972e5..bec3fb0 100644 --- a/spring-boot-16-Transcation/.gitignore +++ b/spring-boot-16-Transcation/.gitignore @@ -1,4 +1,5 @@ .settings/ target/ .classpath -.project \ No newline at end of file +.project +*.iml \ No newline at end of file diff --git a/spring-boot-16-Transcation/spring-boot-16-Transcation.iml b/spring-boot-16-Transcation/spring-boot-16-Transcation.iml deleted file mode 100644 index 2db83f7..0000000 --- a/spring-boot-16-Transcation/spring-boot-16-Transcation.iml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-17-monitor/.gitignore b/spring-boot-17-monitor/.gitignore index 40b1a1d..bec3fb0 100644 --- a/spring-boot-17-monitor/.gitignore +++ b/spring-boot-17-monitor/.gitignore @@ -2,5 +2,4 @@ target/ .classpath .project -logs/ -./logs/ \ No newline at end of file +*.iml \ No newline at end of file diff --git a/spring-boot-17-monitor/spring-boot-17-monitor-AdminClient/.gitignore b/spring-boot-17-monitor/spring-boot-17-monitor-AdminClient/.gitignore index 40b1a1d..bec3fb0 100644 --- a/spring-boot-17-monitor/spring-boot-17-monitor-AdminClient/.gitignore +++ b/spring-boot-17-monitor/spring-boot-17-monitor-AdminClient/.gitignore @@ -2,5 +2,4 @@ target/ .classpath .project -logs/ -./logs/ \ No newline at end of file +*.iml \ No newline at end of file diff --git a/spring-boot-17-monitor/spring-boot-17-monitor-AdminClient/spring-boot-17-monitor-AdminClient.iml b/spring-boot-17-monitor/spring-boot-17-monitor-AdminClient/spring-boot-17-monitor-AdminClient.iml deleted file mode 100644 index 8671704..0000000 --- a/spring-boot-17-monitor/spring-boot-17-monitor-AdminClient/spring-boot-17-monitor-AdminClient.iml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-17-monitor/spring-boot-17-monitor-AdminServer/.gitignore b/spring-boot-17-monitor/spring-boot-17-monitor-AdminServer/.gitignore index 40b1a1d..bec3fb0 100644 --- a/spring-boot-17-monitor/spring-boot-17-monitor-AdminServer/.gitignore +++ b/spring-boot-17-monitor/spring-boot-17-monitor-AdminServer/.gitignore @@ -2,5 +2,4 @@ target/ .classpath .project -logs/ -./logs/ \ No newline at end of file +*.iml \ No newline at end of file diff --git a/spring-boot-17-monitor/spring-boot-17-monitor-AdminServer/spring-boot-17-monitor-AdminServer.iml b/spring-boot-17-monitor/spring-boot-17-monitor-AdminServer/spring-boot-17-monitor-AdminServer.iml deleted file mode 100644 index 5b0b327..0000000 --- a/spring-boot-17-monitor/spring-boot-17-monitor-AdminServer/spring-boot-17-monitor-AdminServer.iml +++ /dev/null @@ -1,115 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-17-monitor/spring-boot-17-monitor-actuator/.gitignore b/spring-boot-17-monitor/spring-boot-17-monitor-actuator/.gitignore index 40b1a1d..bec3fb0 100644 --- a/spring-boot-17-monitor/spring-boot-17-monitor-actuator/.gitignore +++ b/spring-boot-17-monitor/spring-boot-17-monitor-actuator/.gitignore @@ -2,5 +2,4 @@ target/ .classpath .project -logs/ -./logs/ \ No newline at end of file +*.iml \ No newline at end of file diff --git a/spring-boot-17-monitor/spring-boot-17-monitor-actuator/spring-boot-17-monitor-actuator.iml b/spring-boot-17-monitor/spring-boot-17-monitor-actuator/spring-boot-17-monitor-actuator.iml deleted file mode 100644 index ea87bbd..0000000 --- a/spring-boot-17-monitor/spring-boot-17-monitor-actuator/spring-boot-17-monitor-actuator.iml +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-17-monitor/spring-boot-17-monitor.iml b/spring-boot-17-monitor/spring-boot-17-monitor.iml deleted file mode 100644 index a0d4a1e..0000000 --- a/spring-boot-17-monitor/spring-boot-17-monitor.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-18-MQ/.gitignore b/spring-boot-18-MQ/.gitignore index 28972e5..bec3fb0 100644 --- a/spring-boot-18-MQ/.gitignore +++ b/spring-boot-18-MQ/.gitignore @@ -1,4 +1,5 @@ .settings/ target/ .classpath -.project \ No newline at end of file +.project +*.iml \ No newline at end of file diff --git a/spring-boot-18-MQ/pom.xml b/spring-boot-18-MQ/pom.xml index 613be80..d07e43c 100644 --- a/spring-boot-18-MQ/pom.xml +++ b/spring-boot-18-MQ/pom.xml @@ -95,9 +95,9 @@ 128m 512m true - 1.3 + 1.8 UTF-8 - -verbose -bootclasspath ${java.home}\lib\rt.jar + diff --git a/spring-boot-18-MQ/spring-boot-18-MQ-activemq/.gitignore b/spring-boot-18-MQ/spring-boot-18-MQ-activemq/.gitignore index 28972e5..bec3fb0 100644 --- a/spring-boot-18-MQ/spring-boot-18-MQ-activemq/.gitignore +++ b/spring-boot-18-MQ/spring-boot-18-MQ-activemq/.gitignore @@ -1,4 +1,5 @@ .settings/ target/ .classpath -.project \ No newline at end of file +.project +*.iml \ No newline at end of file diff --git a/spring-boot-18-MQ/spring-boot-18-MQ-activemq/spring-boot-18-MQ-activemq.iml b/spring-boot-18-MQ/spring-boot-18-MQ-activemq/spring-boot-18-MQ-activemq.iml deleted file mode 100644 index d579b2d..0000000 --- a/spring-boot-18-MQ/spring-boot-18-MQ-activemq/spring-boot-18-MQ-activemq.iml +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-18-MQ/spring-boot-18-MQ-kafka/.gitignore b/spring-boot-18-MQ/spring-boot-18-MQ-kafka/.gitignore index 28972e5..bec3fb0 100644 --- a/spring-boot-18-MQ/spring-boot-18-MQ-kafka/.gitignore +++ b/spring-boot-18-MQ/spring-boot-18-MQ-kafka/.gitignore @@ -1,4 +1,5 @@ .settings/ target/ .classpath -.project \ No newline at end of file +.project +*.iml \ No newline at end of file diff --git a/spring-boot-18-MQ/spring-boot-18-MQ-kafka/pom.xml b/spring-boot-18-MQ/spring-boot-18-MQ-kafka/pom.xml index dc46479..151930d 100644 --- a/spring-boot-18-MQ/spring-boot-18-MQ-kafka/pom.xml +++ b/spring-boot-18-MQ/spring-boot-18-MQ-kafka/pom.xml @@ -1,18 +1,36 @@ - 4.0.0 - - cn.timebusker - spring-boot-18-MQ - 2.0.0 - - spring-boot-18-MQ-kafka - spring-boot-18-MQ-kafka - http://maven.apache.org - - UTF-8 - - - + xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + 4.0.0 + + cn.timebusker + spring-boot-18-MQ + 2.0.0 + + spring-boot-18-MQ-kafka + spring-boot-18-MQ-kafka + http://maven.apache.org + + UTF-8 + + + + + org.springframework.kafka + spring-kafka + 1.1.1.RELEASE + + + + diff --git a/spring-boot-18-MQ/spring-boot-18-MQ-kafka/spring-boot-18-MQ-kafka.iml b/spring-boot-18-MQ/spring-boot-18-MQ-kafka/spring-boot-18-MQ-kafka.iml deleted file mode 100644 index fe23b83..0000000 --- a/spring-boot-18-MQ/spring-boot-18-MQ-kafka/spring-boot-18-MQ-kafka.iml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/java/cn/timebusker/App.java b/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/java/cn/timebusker/App.java index 8b96064..f9f0a29 100644 --- a/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/java/cn/timebusker/App.java +++ b/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/java/cn/timebusker/App.java @@ -1,9 +1,26 @@ package cn.timebusker; +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.apache.kafka.common.serialization.StringSerializer; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.annotation.EnableKafka; +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; +import org.springframework.kafka.config.KafkaListenerContainerFactory; +import org.springframework.kafka.core.*; +import org.springframework.kafka.listener.ConcurrentMessageListenerContainer; + +import java.util.HashMap; +import java.util.Map; @SpringBootApplication +@Configuration +@EnableKafka public class App { public static void main(String[] args) { diff --git a/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/java/cn/timebusker/KafkaConfig.java b/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/java/cn/timebusker/KafkaConfig.java new file mode 100644 index 0000000..db8ecf9 --- /dev/null +++ b/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/java/cn/timebusker/KafkaConfig.java @@ -0,0 +1,94 @@ +package cn.timebusker; + +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.apache.kafka.common.serialization.StringSerializer; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; +import org.springframework.kafka.config.KafkaListenerContainerFactory; +import org.springframework.kafka.core.*; +import org.springframework.kafka.listener.ConcurrentMessageListenerContainer; + +import java.util.HashMap; +import java.util.Map; + +/** + * @DESC:KafkaConfig + * @author:timebusker + * @date:2018/12/20 + */ +@Configuration +public class KafkaConfig { + + // 消费端配置 + @Value("${kafka.consumer.servers}") + private String consumerservers; + @Value("${kafka.consumer.enable.auto.commit}") + private boolean enableAutoCommit; + @Value("${kafka.consumer.session.timeout}") + private String sessionTimeout; + @Value("${kafka.consumer.auto.commit.interval}") + private String autoCommitInterval; + @Value("${kafka.consumer.group.id}") + private String groupId; + @Value("${kafka.consumer.auto.offset.reset}") + private String autoOffsetReset; + @Value("${kafka.consumer.concurrency}") + private int concurrency; + + // 生产端配置 + @Value("${kafka.producer.servers}") + private String servers; + @Value("${kafka.producer.retries}") + private int retries; + @Value("${kafka.producer.batch.size}") + private int batchSize; + @Value("${kafka.producer.linger}") + private int linger; + @Value("${kafka.producer.buffer.memory}") + private int bufferMemory; + + @Bean("kafkaTemplate") + public KafkaTemplate getKafkaTemplate(){ + Map props = new HashMap<>(); + props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, servers); + props.put(ProducerConfig.RETRIES_CONFIG, retries); + props.put(ProducerConfig.BATCH_SIZE_CONFIG, batchSize); + props.put(ProducerConfig.LINGER_MS_CONFIG, linger); + props.put(ProducerConfig.BUFFER_MEMORY_CONFIG, bufferMemory); + props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + KafkaTemplate template = new KafkaTemplate(new DefaultKafkaProducerFactory<>(props)); + return template; + } + + @Bean + public KafkaListenerContainerFactory> kafkaListenerContainerFactory() { + ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(consumerFactory()); + factory.setConcurrency(concurrency); + factory.getContainerProperties().setPollTimeout(1500); + return factory; + } + + public ConsumerFactory consumerFactory() { + return new DefaultKafkaConsumerFactory<>(consumerConfigs()); + } + + + public Map consumerConfigs() { + Map propsMap = new HashMap<>(); + propsMap.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, servers); + propsMap.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, enableAutoCommit); + propsMap.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, autoCommitInterval); + propsMap.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, sessionTimeout); + propsMap.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); + propsMap.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); + propsMap.put(ConsumerConfig.GROUP_ID_CONFIG, groupId); + propsMap.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, autoOffsetReset); + return propsMap; + } +} diff --git a/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/java/cn/timebusker/mq/KafkaConsumerService.java b/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/java/cn/timebusker/mq/KafkaConsumerService.java new file mode 100644 index 0000000..b2ce8f4 --- /dev/null +++ b/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/java/cn/timebusker/mq/KafkaConsumerService.java @@ -0,0 +1,21 @@ +package cn.timebusker.mq; + +import com.alibaba.fastjson.JSON; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.stereotype.Service; + +/** + * @DESC:KafkaConsumerService:消息消费 + * @author:timebusker + * @date:2018/9/13 + */ +@Service +public class KafkaConsumerService { + + @KafkaListener(topics = {"test"}) + public void consume(String message){ + System.out.println(message); + } +} diff --git a/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/java/cn/timebusker/mq/KafkaProducerService.java b/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/java/cn/timebusker/mq/KafkaProducerService.java new file mode 100644 index 0000000..4e1707b --- /dev/null +++ b/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/java/cn/timebusker/mq/KafkaProducerService.java @@ -0,0 +1,29 @@ +package cn.timebusker.mq; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.stereotype.Service; + +/** + * @DESC:KafkaProducer:消息投递 + * @author:timebusker + * @date:2018/9/13 + */ +@Service +public class KafkaProducerService { + + private final static Logger logger = LoggerFactory.getLogger(KafkaProducerService.class); + + @Autowired + private KafkaTemplate kafkaTemplate; + + public void produce(String topic,String message){ + try { + kafkaTemplate.send(topic,message); + }catch (Exception e){ + logger.info(e.getMessage()); + } + } +} diff --git a/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/java/cn/timebusker/task/KafkaTaskService.java b/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/java/cn/timebusker/task/KafkaTaskService.java new file mode 100644 index 0000000..fd4aec2 --- /dev/null +++ b/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/java/cn/timebusker/task/KafkaTaskService.java @@ -0,0 +1,35 @@ +package cn.timebusker.task; + +import cn.timebusker.mq.KafkaProducerService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * @DESC:KafkaTaskService + * @author:timebusker + * @date:2018/9/13 + */ +@Service +@Configuration +@EnableScheduling +public class KafkaTaskService { + + @Autowired + private KafkaProducerService service; + + private final static String TOPIC = "test"; + + @Scheduled(fixedDelay = 1000) + public void testKafka() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS"); + String date = sdf.format(new Date()); + String obj = "当前测试消息时间是:\t" + date; + service.produce(TOPIC, obj); + } +} diff --git a/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/resources/application-dev.properties b/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/resources/application-dev.properties index 8ca4a30..08cc23e 100644 --- a/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/resources/application-dev.properties +++ b/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/resources/application-dev.properties @@ -1,36 +1,27 @@ -# 项目contextPath,一般在正式发布版本中,我们不配置 +# \u9879\u76EEcontextPath\uFF0C\u4E00\u822C\u5728\u6B63\u5F0F\u53D1\u5E03\u7248\u672C\u4E2D\uFF0C\u6211\u4EEC\u4E0D\u914D\u7F6E # server.context-path=/mq -# 错误页,指定发生错误时,跳转的URL。请查看BasicErrorController源码便知 +# \u9519\u8BEF\u9875\uFF0C\u6307\u5B9A\u53D1\u751F\u9519\u8BEF\u65F6\uFF0C\u8DF3\u8F6C\u7684URL\u3002\u8BF7\u67E5\u770BBasicErrorController\u6E90\u7801\u4FBF\u77E5 server.error.path=/error -# 服务端口 +# \u670D\u52A1\u7AEF\u53E3 server.port=80 -# session最大超时时间(分钟),默认为30 +# session\u6700\u5927\u8D85\u65F6\u65F6\u95F4(\u5206\u949F)\uFF0C\u9ED8\u8BA4\u4E3A30 server.session-timeout=60 -# 该服务绑定IP地址,启动服务器时如本机不是该IP地址则抛出异常启动失败,只有特殊需求的情况下才配置 +# \u8BE5\u670D\u52A1\u7ED1\u5B9AIP\u5730\u5740\uFF0C\u542F\u52A8\u670D\u52A1\u5668\u65F6\u5982\u672C\u673A\u4E0D\u662F\u8BE5IP\u5730\u5740\u5219\u629B\u51FA\u5F02\u5E38\u542F\u52A8\u5931\u8D25\uFF0C\u53EA\u6709\u7279\u6B8A\u9700\u6C42\u7684\u60C5\u51B5\u4E0B\u624D\u914D\u7F6E # server.address=192.168.16.11 -# ACTIVEMQ -# 配置消息模型为pub/sub方式:true是Topic;如果是false或者默认,则是queue -spring.jms.pub-sub-domain=true -# URL of the ActiveMQ broker. Auto-generated by default. For instance `tcp://localhost:61616` -# spring.activemq.broker-url= -# Specify if the default broker URL should be in memory. Ignored if an explicit broker has been specified. -# spring.activemq.in-memory=true -# Login password of the broker. -# spring.activemq.password= -# Login user of the broker. -# spring.activemq.user= -# Trust all packages. -# spring.activemq.packages.trust-all=false -# Comma-separated list of specific packages to trust (when not trusting all packages). -# spring.activemq.packages.trusted= -# See PooledConnectionFactory. -# spring.activemq.pool.configuration.*= -# Whether a PooledConnectionFactory should be created instead of a regular ConnectionFactory. -# spring.activemq.pool.enabled=false -# Connection expiration timeout in milliseconds. -# spring.activemq.pool.expiry-timeout=0 -# Connection idle timeout in milliseconds. -# spring.activemq.pool.idle-timeout=30000 -# Maximum number of pooled connections. -# spring.activemq.pool.max-connections=1 \ No newline at end of file +#kafka\u76F8\u5173\u914D\u7F6E +kafka.consumer.zookeeper.connect=127.0.0.1:2181 +kafka.consumer.servers=127.0.0.1:9092 +kafka.consumer.enable.auto.commit=true +kafka.consumer.session.timeout=6000 +kafka.consumer.auto.commit.interval=100 +kafka.consumer.auto.offset.reset=latest +kafka.consumer.topic=tepst +kafka.consumer.group.id=test +kafka.consumer.concurrency=10 + +kafka.producer.servers=127.0.0.1:9092 +kafka.producer.retries=0 +kafka.producer.batch.size=4096 +kafka.producer.linger=1 +kafka.producer.buffer.memory=40960 \ No newline at end of file diff --git a/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/resources/logback.xml b/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/resources/logback.xml index fb1ed91..471fe57 100644 --- a/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/resources/logback.xml +++ b/spring-boot-18-MQ/spring-boot-18-MQ-kafka/src/main/resources/logback.xml @@ -1,6 +1,5 @@ - @@ -8,9 +7,21 @@ %date [%thread] %-5level %logger{80} || %msg%n + + /logs/timebusker.log + + /logs/timebusker-%d{yyyy-MM-dd}.log + 30 + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n + + false + false + + - diff --git a/spring-boot-18-MQ/spring-boot-18-MQ-rabbitmq/.gitignore b/spring-boot-18-MQ/spring-boot-18-MQ-rabbitmq/.gitignore index 28972e5..bec3fb0 100644 --- a/spring-boot-18-MQ/spring-boot-18-MQ-rabbitmq/.gitignore +++ b/spring-boot-18-MQ/spring-boot-18-MQ-rabbitmq/.gitignore @@ -1,4 +1,5 @@ .settings/ target/ .classpath -.project \ No newline at end of file +.project +*.iml \ No newline at end of file diff --git a/spring-boot-18-MQ/spring-boot-18-MQ-rabbitmq/spring-boot-18-MQ-rabbitmq.iml b/spring-boot-18-MQ/spring-boot-18-MQ-rabbitmq/spring-boot-18-MQ-rabbitmq.iml deleted file mode 100644 index 7d9eca0..0000000 --- a/spring-boot-18-MQ/spring-boot-18-MQ-rabbitmq/spring-boot-18-MQ-rabbitmq.iml +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-18-MQ/spring-boot-18-MQ-rocketmq/.gitignore b/spring-boot-18-MQ/spring-boot-18-MQ-rocketmq/.gitignore index 28972e5..bec3fb0 100644 --- a/spring-boot-18-MQ/spring-boot-18-MQ-rocketmq/.gitignore +++ b/spring-boot-18-MQ/spring-boot-18-MQ-rocketmq/.gitignore @@ -1,4 +1,5 @@ .settings/ target/ .classpath -.project \ No newline at end of file +.project +*.iml \ No newline at end of file diff --git a/spring-boot-18-MQ/spring-boot-18-MQ-rocketmq/spring-boot-18-MQ-rocketmq.iml b/spring-boot-18-MQ/spring-boot-18-MQ-rocketmq/spring-boot-18-MQ-rocketmq.iml deleted file mode 100644 index fe23b83..0000000 --- a/spring-boot-18-MQ/spring-boot-18-MQ-rocketmq/spring-boot-18-MQ-rocketmq.iml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-18-MQ/spring-boot-18-MQ.iml b/spring-boot-18-MQ/spring-boot-18-MQ.iml deleted file mode 100644 index d84a458..0000000 --- a/spring-boot-18-MQ/spring-boot-18-MQ.iml +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-19-Definition-Starter/.gitignore b/spring-boot-19-Definition-Starter/.gitignore new file mode 100644 index 0000000..bec3fb0 --- /dev/null +++ b/spring-boot-19-Definition-Starter/.gitignore @@ -0,0 +1,5 @@ +.settings/ +target/ +.classpath +.project +*.iml \ No newline at end of file diff --git a/spring-boot-19-Definition-Starter/pom.xml b/spring-boot-19-Definition-Starter/pom.xml index 145e15d..bd37cc0 100644 --- a/spring-boot-19-Definition-Starter/pom.xml +++ b/spring-boot-19-Definition-Starter/pom.xml @@ -21,10 +21,6 @@ - - UTF-8 - - diff --git a/spring-boot-19-Definition-Starter/spring-boot-19-Definition-Starter-Service/.gitignore b/spring-boot-19-Definition-Starter/spring-boot-19-Definition-Starter-Service/.gitignore new file mode 100644 index 0000000..bec3fb0 --- /dev/null +++ b/spring-boot-19-Definition-Starter/spring-boot-19-Definition-Starter-Service/.gitignore @@ -0,0 +1,5 @@ +.settings/ +target/ +.classpath +.project +*.iml \ No newline at end of file diff --git a/spring-boot-19-Definition-Starter/spring-boot-19-Definition-Starter-Service/spring-boot-19-Definition-Starter-Service.iml b/spring-boot-19-Definition-Starter/spring-boot-19-Definition-Starter-Service/spring-boot-19-Definition-Starter-Service.iml deleted file mode 100644 index a45d83e..0000000 --- a/spring-boot-19-Definition-Starter/spring-boot-19-Definition-Starter-Service/spring-boot-19-Definition-Starter-Service.iml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-19-Definition-Starter/spring-boot-19-Definition-Starter-Test/.gitignore b/spring-boot-19-Definition-Starter/spring-boot-19-Definition-Starter-Test/.gitignore new file mode 100644 index 0000000..bec3fb0 --- /dev/null +++ b/spring-boot-19-Definition-Starter/spring-boot-19-Definition-Starter-Test/.gitignore @@ -0,0 +1,5 @@ +.settings/ +target/ +.classpath +.project +*.iml \ No newline at end of file diff --git a/spring-boot-19-Definition-Starter/spring-boot-19-Definition-Starter-Test/spring-boot-19-Definition-Starter-Test.iml b/spring-boot-19-Definition-Starter/spring-boot-19-Definition-Starter-Test/spring-boot-19-Definition-Starter-Test.iml deleted file mode 100644 index 8dde4e6..0000000 --- a/spring-boot-19-Definition-Starter/spring-boot-19-Definition-Starter-Test/spring-boot-19-Definition-Starter-Test.iml +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-19-Definition-Starter/spring-boot-19-Definition-Starter.iml b/spring-boot-19-Definition-Starter/spring-boot-19-Definition-Starter.iml deleted file mode 100644 index b265ef6..0000000 --- a/spring-boot-19-Definition-Starter/spring-boot-19-Definition-Starter.iml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-2-RESTful/.gitignore b/spring-boot-2-RESTful/.gitignore new file mode 100644 index 0000000..bec3fb0 --- /dev/null +++ b/spring-boot-2-RESTful/.gitignore @@ -0,0 +1,5 @@ +.settings/ +target/ +.classpath +.project +*.iml \ No newline at end of file diff --git a/spring-boot-2-RESTful/pom.xml b/spring-boot-2-RESTful/pom.xml index 112f96f..32950c4 100644 --- a/spring-boot-2-RESTful/pom.xml +++ b/spring-boot-2-RESTful/pom.xml @@ -64,9 +64,4 @@ fastjson
- - - spring-boot-2-RESTful - - diff --git a/spring-boot-2-RESTful/spring-boot-2-RESTful.iml b/spring-boot-2-RESTful/spring-boot-2-RESTful.iml deleted file mode 100644 index 4a71d9f..0000000 --- a/spring-boot-2-RESTful/spring-boot-2-RESTful.iml +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-20-Freemarker/README.md b/spring-boot-20-Freemarker/README.md new file mode 100644 index 0000000..6817a09 --- /dev/null +++ b/spring-boot-20-Freemarker/README.md @@ -0,0 +1,62 @@ +1.@ComponentScan(basePackages={"com.spring"}) 这个注解的意思是通过spring容 +器去加载以com.spring开头的包下面的内容。 + +2.<#assign var="hello spring boot"/> +freemarker标签用于声明一个变量 + +3.@Configuration注解会默认加载resources下的配置文件。 + +4.freemarker不支持boolean类型的true/false。输出是会抛出异常! +但是可以转化:布尔值: ${booleanVar?string('yes','no')} + + +5.<#if myList??> 表示判断myList变量是不是存在或是不是空值 +等同于<#if myList?exists> + +6.freemarker内建指令以#开始,自定义指令以@开始 +<@role user='123456' role='admin';result1,result2> +user用户id,role用户权限 + +7.Freemarker的内建函数就是直接可以使用的函数,是freemarker封装好的函数。 +有处理字符串,数字,list的内建函数。 +处理字符串内建函数: +substring 字符串的截取 +cap_first 首字母变大写 +ends_with 以...结尾的函数 +contains 字符串是否包含目标字符串的函数 +如何把一个字符串转化为date 、datetime 、time类型的函数 date datetime time; +starts_with 字符串以...开始 +index_of 字符串所在的位置 +last_index_of 字符串最后所在的位置 +split 分割字符串 +trim 去掉字符串两头的空格 +等函数 + + 处理数字的内建函数 +string x?string("0.##") 对数字进行格式化 +round 四舍五入 +floor 把小数点去掉 +ceiling 数字进1,变成整数 + +处理list内建函数: +first 取list第一个值 +last 取list最后一个值 +seq_contains 这个序列是否包含 +seq_index_of 这个序列所在的位置 +size list长度 +reverse 倒序 +sort 升序排序 +sort_by 根据属性排序 +trunk 把字符串分块处理 + +其他内建函数 +is函数:判断变量的类型 +is_string 字符串 +is_number 整数 +is_method 方法 + +() 对变量进行判断 +hs_content 判断对象是否是空值,是不是有内容 +eval 求值函数 + +8.<#nested param1,"我的nested参数"> 用来定义模板片段 \ No newline at end of file diff --git a/spring-boot-20-Freemarker/doc/1.png b/spring-boot-20-Freemarker/doc/1.png new file mode 100644 index 0000000..1cbb542 Binary files /dev/null and b/spring-boot-20-Freemarker/doc/1.png differ diff --git "a/spring-boot-20-Freemarker/doc/Freemarker\345\277\253\351\200\237\345\205\245\351\227\250.pdf" "b/spring-boot-20-Freemarker/doc/Freemarker\345\277\253\351\200\237\345\205\245\351\227\250.pdf" new file mode 100644 index 0000000..830f33f Binary files /dev/null and "b/spring-boot-20-Freemarker/doc/Freemarker\345\277\253\351\200\237\345\205\245\351\227\250.pdf" differ diff --git "a/spring-boot-20-Freemarker/doc/freemarker\344\270\255\346\226\207\346\211\213\345\206\214.pdf" "b/spring-boot-20-Freemarker/doc/freemarker\344\270\255\346\226\207\346\211\213\345\206\214.pdf" new file mode 100644 index 0000000..4adfce1 Binary files /dev/null and "b/spring-boot-20-Freemarker/doc/freemarker\344\270\255\346\226\207\346\211\213\345\206\214.pdf" differ diff --git "a/spring-boot-20-Freemarker/doc/\344\270\215\351\224\231\347\232\204FreeMarker\346\225\231\347\250\213.pdf" "b/spring-boot-20-Freemarker/doc/\344\270\215\351\224\231\347\232\204FreeMarker\346\225\231\347\250\213.pdf" new file mode 100644 index 0000000..2e47428 Binary files /dev/null and "b/spring-boot-20-Freemarker/doc/\344\270\215\351\224\231\347\232\204FreeMarker\346\225\231\347\250\213.pdf" differ diff --git a/spring-boot-20-Freemarker/pom.xml b/spring-boot-20-Freemarker/pom.xml new file mode 100644 index 0000000..da570c5 --- /dev/null +++ b/spring-boot-20-Freemarker/pom.xml @@ -0,0 +1,29 @@ + + + + spring-boot + cn.timebusker + 2.0.0 + + 4.0.0 + + spring-boot-20-Freemarker + + + + org.springframework.boot + spring-boot-starter-freemarker + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter + + + + \ No newline at end of file diff --git a/spring-boot-20-Freemarker/src/main/java/com/timebusker/App.java b/spring-boot-20-Freemarker/src/main/java/com/timebusker/App.java new file mode 100644 index 0000000..e4ceba3 --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/java/com/timebusker/App.java @@ -0,0 +1,22 @@ +package com.timebusker; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @DESC:Application + * @author:timebusker + * @date:2018/6/23 + */ +@SpringBootApplication +public class App { + private final static Logger LOG = LoggerFactory.getLogger(App.class); + + public static void main(String[] args) { + SpringApplication.run(App.class, args); + LOG.info("启动应用成功..."); + LOG.info("设置参数是:" + args.toString()); + } +} diff --git a/spring-boot-20-Freemarker/src/main/java/com/timebusker/common/HttpStatus.java b/spring-boot-20-Freemarker/src/main/java/com/timebusker/common/HttpStatus.java new file mode 100644 index 0000000..c5f4ed4 --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/java/com/timebusker/common/HttpStatus.java @@ -0,0 +1,57 @@ +package com.timebusker.common; + +/** + * @DESC:HttpStatus + * @author:timebusker + * @date:2018/6/23 + */ +public interface HttpStatus { + int SC_CONTINUE = 100; + int SC_SWITCHING_PROTOCOLS = 101; + int SC_PROCESSING = 102; + int SC_OK = 200; + int SC_CREATED = 201; + int SC_ACCEPTED = 202; + int SC_NON_AUTHORITATIVE_INFORMATION = 203; + int SC_NO_CONTENT = 204; + int SC_RESET_CONTENT = 205; + int SC_PARTIAL_CONTENT = 206; + int SC_MULTI_STATUS = 207; + int SC_MULTIPLE_CHOICES = 300; + int SC_MOVED_PERMANENTLY = 301; + int SC_MOVED_TEMPORARILY = 302; + int SC_SEE_OTHER = 303; + int SC_NOT_MODIFIED = 304; + int SC_USE_PROXY = 305; + int SC_TEMPORARY_REDIRECT = 307; + int SC_BAD_REQUEST = 400; + int SC_UNAUTHORIZED = 401; + int SC_PAYMENT_REQUIRED = 402; + int SC_FORBIDDEN = 403; + int SC_NOT_FOUND = 404; + int SC_METHOD_NOT_ALLOWED = 405; + int SC_NOT_ACCEPTABLE = 406; + int SC_PROXY_AUTHENTICATION_REQUIRED = 407; + int SC_REQUEST_TIMEOUT = 408; + int SC_CONFLICT = 409; + int SC_GONE = 410; + int SC_LENGTH_REQUIRED = 411; + int SC_PRECONDITION_FAILED = 412; + int SC_REQUEST_TOO_LONG = 413; + int SC_REQUEST_URI_TOO_LONG = 414; + int SC_UNSUPPORTED_MEDIA_TYPE = 415; + int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416; + int SC_EXPECTATION_FAILED = 417; + int SC_INSUFFICIENT_SPACE_ON_RESOURCE = 419; + int SC_METHOD_FAILURE = 420; + int SC_UNPROCESSABLE_ENTITY = 422; + int SC_LOCKED = 423; + int SC_FAILED_DEPENDENCY = 424; + int SC_INTERNAL_SERVER_ERROR = 500; + int SC_NOT_IMPLEMENTED = 501; + int SC_BAD_GATEWAY = 502; + int SC_SERVICE_UNAVAILABLE = 503; + int SC_GATEWAY_TIMEOUT = 504; + int SC_HTTP_VERSION_NOT_SUPPORTED = 505; + int SC_INSUFFICIENT_STORAGE = 507; +} diff --git a/spring-boot-20-Freemarker/src/main/java/com/timebusker/common/ResEntity.java b/spring-boot-20-Freemarker/src/main/java/com/timebusker/common/ResEntity.java new file mode 100644 index 0000000..709f60e --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/java/com/timebusker/common/ResEntity.java @@ -0,0 +1,54 @@ +package com.timebusker.common; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/** + * @DESC:ResEntity:数据返回结果集 + * @author:timebusker + * @date:2018/6/23 + */ +public class ResEntity extends HashMap implements Serializable { + private static final long serialVersionUID = 1L; + + public ResEntity() { + put("code", 0); + } + + public static ResEntity error() { + return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员"); + } + + public static ResEntity error(String msg) { + return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg); + } + + public static ResEntity error(int code, String msg) { + ResEntity r = new ResEntity(); + r.put("code", code); + r.put("msg", msg); + return r; + } + + public static ResEntity ok(String msg) { + ResEntity r = new ResEntity(); + r.put("msg", msg); + return r; + } + + public static ResEntity ok(Map map) { + ResEntity r = new ResEntity(); + r.putAll(map); + return r; + } + + public static ResEntity ok() { + return new ResEntity(); + } + + public ResEntity put(String key, Object value) { + super.put(key, value); + return this; + } +} diff --git a/spring-boot-20-Freemarker/src/main/java/com/timebusker/entity/UserInfo.java b/spring-boot-20-Freemarker/src/main/java/com/timebusker/entity/UserInfo.java new file mode 100644 index 0000000..246b8a8 --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/java/com/timebusker/entity/UserInfo.java @@ -0,0 +1,48 @@ +package com.timebusker.entity; + +/** + * @DESC:UserInfo + * @author:timebusker + * @date:2018/6/23 + */ +public class UserInfo { + private final static int st = 0; + private String username; + private String password; + private String uid; + + public UserInfo(String uid, String username, String password) { + this.username = username; + this.password = password; + this.uid = uid; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getUid() { + return uid; + } + + public void setUid(String uid) { + this.uid = uid; + } + + @Override + public String toString() { + return String.format("UserInfo:[uid:%s,username:%s,password:%s]", uid, username, password); + } +} diff --git a/spring-boot-20-Freemarker/src/main/java/com/timebusker/method/RoleDirectiveModel.java b/spring-boot-20-Freemarker/src/main/java/com/timebusker/method/RoleDirectiveModel.java new file mode 100644 index 0000000..a9c8902 --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/java/com/timebusker/method/RoleDirectiveModel.java @@ -0,0 +1,52 @@ +package com.timebusker.method; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.springframework.stereotype.Service; + +import freemarker.core.Environment; +import freemarker.template.SimpleSequence; +import freemarker.template.TemplateBooleanModel; +import freemarker.template.TemplateDirectiveBody; +import freemarker.template.TemplateDirectiveModel; +import freemarker.template.TemplateException; +import freemarker.template.TemplateModel; +import freemarker.template.TemplateScalarModel; + +@Service +public class RoleDirectiveModel implements TemplateDirectiveModel{ + + /* + *env:环境变量 + *params:指令参数(存储你所需要的值,随便是什么key-Value你懂的) + *loopVars:循环变量 + *body:指令内容 + *除了params外,其他的都使用null + */ + @Override + public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) + throws TemplateException, IOException { + System.out.println("自定义指令需要实现TemplateDirectiveModel接口"); + //获取参数 + TemplateScalarModel user = (TemplateScalarModel) params.get("user"); + TemplateScalarModel role = (TemplateScalarModel) params.get("role"); + + if("123456".equals(user.getAsString()) && "admin".equals(role.getAsString())){ + //用户id + loopVars[0] = TemplateBooleanModel.TRUE; + } + + //创建用户的权限 + List otherRights = new ArrayList(); + otherRights.add("add"); + otherRights.add("delete"); + otherRights.add("update"); + loopVars[1] = new SimpleSequence(otherRights); + + body.render(env.getOut()); + } + +} diff --git a/spring-boot-20-Freemarker/src/main/java/com/timebusker/method/SortMethod.java b/spring-boot-20-Freemarker/src/main/java/com/timebusker/method/SortMethod.java new file mode 100644 index 0000000..f077079 --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/java/com/timebusker/method/SortMethod.java @@ -0,0 +1,31 @@ +package com.timebusker.method; + +import freemarker.template.*; + +import java.math.BigDecimal; +import java.util.*; + +/** + * @DESC:freeMethod + * @author:timebusker + * @date:2018/6/24 + */ +public class SortMethod implements TemplateMethodModelEx { + @Override + public Object exec(List arguments) throws TemplateModelException { + //获取第一个参数 + SimpleSequence arg0 = (SimpleSequence) arguments.get(0); + List list = arg0.toList(); + //Comparator接口 + Collections.sort(list, new Comparator() { + + @Override + public int compare(BigDecimal o1, BigDecimal o2) { + + return o1.intValue() - o2.intValue(); //升序 + } + + }); + return list; + } +} diff --git a/spring-boot-20-Freemarker/src/main/java/com/timebusker/service/UserInfoService.java b/spring-boot-20-Freemarker/src/main/java/com/timebusker/service/UserInfoService.java new file mode 100644 index 0000000..0b49711 --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/java/com/timebusker/service/UserInfoService.java @@ -0,0 +1,52 @@ +package com.timebusker.service; + +import com.timebusker.entity.UserInfo; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; + +/** + * @DESC:UserInfoService + * @author:timebusker + * @date:2018/6/23 + */ +@Service +public class UserInfoService { + private static Map hu = new HashMap<>(); + + static { + UserInfo u1 = new UserInfo("1", "timebusker", "123456"); + UserInfo u2 = new UserInfo("2", "yujiaojiao", "123456"); + UserInfo u3 = new UserInfo("3", "mine", "123456"); + UserInfo u4 = new UserInfo("4", "admin", "123456"); + UserInfo u5 = new UserInfo("5", "popo", "123456"); + hu.put(u1.getUid(), u1); + hu.put(u2.getUid(), u2); + hu.put(u3.getUid(), u3); + hu.put(u4.getUid(), u4); + hu.put(u5.getUid(), u5); + System.out.println("##########################################################\n\n"); + System.out.println(hu.values().iterator().next().getUsername()); + System.out.println("\n\n##########################################################"); + } + + public Map allUser() { + return hu; + } + + public UserInfo getUser() { + return hu.get("1"); + } + + public Map updateUser(UserInfo u) { + hu.remove(u.getUid()); + hu.put(u.getUid(), u); + return hu; + } + + public Map deleteUser(UserInfo u) { + hu.remove(u.getUid()); + return hu; + } +} diff --git a/spring-boot-20-Freemarker/src/main/java/com/timebusker/web/FreemarkerController.java b/spring-boot-20-Freemarker/src/main/java/com/timebusker/web/FreemarkerController.java new file mode 100644 index 0000000..3f9ccf8 --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/java/com/timebusker/web/FreemarkerController.java @@ -0,0 +1,89 @@ +package com.timebusker.web; + +import com.timebusker.method.SortMethod; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.ModelAndView; + +import java.util.*; + +/** + * @DESC:FreemarkerController + * @author:timebusker + * @date:2018/6/24 + */ +@Controller +public class FreemarkerController { + + @RequestMapping(value = "/free0") + public ModelAndView index() { + ModelAndView mv = new ModelAndView(); + mv.addObject("username", "你好!Freemarker!"); + return mv; + } + + //freemarker取值,插值 + @RequestMapping("/free1") + public ModelAndView free1() { + ModelAndView mv1 = new ModelAndView(); + mv1.addObject("intVar", 100); + mv1.addObject("LongVar", 10000000000000000L); + mv1.addObject("doubleVar", 3.141592675d); + mv1.addObject("StringVar", "我是freemarker,是字符串!"); + mv1.addObject("booleanVar", true); + mv1.addObject("dateVar1", new Date()); + mv1.addObject("nullVar1", null); + mv1.addObject("nullVar", "我是空"); + return mv1; + } + + @RequestMapping("/free2") + public ModelAndView free2() { + ModelAndView mv2 = new ModelAndView(); + List list = new ArrayList(); + list.add("java"); + list.add("JavaScript"); + list.add("python"); + list.add("php"); + list.add("Html"); + mv2.addObject("programList", list); + return mv2; + } + + @RequestMapping(value = "/free3") + public ModelAndView free3() { + ModelAndView mv3 = new ModelAndView(); + Map map = new HashMap(); + map.put("Java", "你好Java"); + map.put("address", "北京"); + map.put("身高", 172); + map.put("money", 100.5); + mv3.addObject("map", map); + return mv3; + } + + @RequestMapping("/free4") + public ModelAndView free4() { + ModelAndView mv4 = new ModelAndView(); + mv4.addObject("sort_int", new SortMethod()); + return mv4; + } + + @RequestMapping("/free5") + public ModelAndView free5() { + ModelAndView mv5 = new ModelAndView("free5"); + return mv5; + } + + @RequestMapping(value = "/free6") + public ModelAndView free6() { + ModelAndView mv6 = new ModelAndView(); + return mv6; + } + + @RequestMapping(value = "/free7") + public ModelAndView free7() { + ModelAndView mv7 = new ModelAndView(); + return mv7; + } +} diff --git a/spring-boot-20-Freemarker/src/main/java/com/timebusker/web/IndexController.java b/spring-boot-20-Freemarker/src/main/java/com/timebusker/web/IndexController.java new file mode 100644 index 0000000..82b55d3 --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/java/com/timebusker/web/IndexController.java @@ -0,0 +1,29 @@ +package com.timebusker.web; + +import com.timebusker.entity.UserInfo; +import com.timebusker.service.UserInfoService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.GetMapping; + +import java.util.*; + +/** + * @DESC:IndexController + * @author:timebusker + * @date:2018/6/23 + */ +@Controller +public class IndexController { + + private final static Logger LOG = LoggerFactory.getLogger(IndexController.class); + + @GetMapping({"", "/", "index", "/home"}) + public String index() { + LOG.info("This is the First Page."); + return "index"; + } +} diff --git a/spring-boot-20-Freemarker/src/main/java/com/timebusker/web/UserController.java b/spring-boot-20-Freemarker/src/main/java/com/timebusker/web/UserController.java new file mode 100644 index 0000000..3dd21e3 --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/java/com/timebusker/web/UserController.java @@ -0,0 +1,38 @@ +package com.timebusker.web; + +import com.timebusker.entity.UserInfo; +import com.timebusker.service.UserInfoService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.ModelAndView; + +import java.util.*; + +/** + * @DESC:UserController + * @author:timebusker + * @date:2018/7/5 + */ + +@Controller +public class UserController { + + @Autowired + UserInfoService service; + + @RequestMapping("/entity") + public ModelAndView index() { + ModelAndView mv = new ModelAndView(); + int sum = 12 + 13; + UserInfo u = service.getUser(); + Map hu = service.allUser(); + Collection cu = service.allUser().values(); + List lu = new ArrayList<>(cu); + mv.addObject("sum", sum); + mv.addObject("u", u); + mv.addObject("hu", hu); + mv.addObject("lu", lu); + return mv; + } +} diff --git a/spring-boot-20-Freemarker/src/main/resources/application.properties b/spring-boot-20-Freemarker/src/main/resources/application.properties new file mode 100644 index 0000000..0955382 --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/resources/application.properties @@ -0,0 +1,9 @@ +#\u670D\u52A1\u7AEF\u53E3 +server.port=80 +#freemarker\u914D\u7F6E +spring.freemarker.cache=false +spring.freemarker.checkTemplateLocation=true +spring.freemarker.contentType=text/html +spring.freemarker.suffix=.html +spring.freemarker.templateEncoding=UTF-8 +spring.freemarker.templateLoaderPath=classpath:/templates/ \ No newline at end of file diff --git a/spring-boot-20-Freemarker/src/main/resources/templates/entity.html b/spring-boot-20-Freemarker/src/main/resources/templates/entity.html new file mode 100644 index 0000000..e788ec5 --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/resources/templates/entity.html @@ -0,0 +1,53 @@ + + + + + FreeMarker + + + +

数据绑定

+
    +
  • 单值数据绑定:_____${sum}
  • +
+
+
    +
  • Entity数据绑定:_____${u!"Default"}
  • +
  • + ${u.uid} + ${u.username} + ${u.password} +
  • +
+
+
    +
  • Map数据绑定
  • + <#list hu?keys as key> +
  • + ${key}____ + ${hu[key].uid} + ${hu[key].username} + ${hu[key].password} +
  • + +
+
+
    +
  • List数据绑定
  • + <#list lu as u> +
  • + ${u.uid}____ + ${u.username} + ${u.password} +
  • + +
+ + \ No newline at end of file diff --git a/spring-boot-20-Freemarker/src/main/resources/templates/free0.html b/spring-boot-20-Freemarker/src/main/resources/templates/free0.html new file mode 100644 index 0000000..2d25531 --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/resources/templates/free0.html @@ -0,0 +1,43 @@ + + + + + freemarker + + + +

${username}

+<#assign var="使用assign指令你可以创建一个新的变量,或者替换一个已经存在的变量"/> +${var} +
+ +

字符串

+

字符串常用内建函数

+
    + <#assign a='hello'/> + <#assign b='world!'/> +
  • 连接: ${a+b}
  • + +
  • 截取:${(a+b)?substring(5,8)}
  • + +
  • 长度:${(a+b)?length}
  • + +
  • 大写:${(a+b)?upper_case}
  • + +
  • 小写:${(a+b)?lower_case}
  • + +
  • index_of:${(a+b)?index_of('w')}
  • + +
  • replace:${(a+b)?replace('o','abc')}
  • + +
  • last_index_of:${(a+b)?last_index_of('o')}
  • +
+ + \ No newline at end of file diff --git a/spring-boot-20-Freemarker/src/main/resources/templates/free1.html b/spring-boot-20-Freemarker/src/main/resources/templates/free1.html new file mode 100644 index 0000000..aa5ae2b --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/resources/templates/free1.html @@ -0,0 +1,38 @@ + + + + + timebusker + + + +

取值:

+
+
    +
  • 整数:${intVar}
  • +
  • 长整数:${LongVar}
  • +
  • 双精度:${doubleVar}
  • +
  • 字符串:${StringVar}
  • +
  • 布尔值: ${booleanVar?string('yes','no')}
  • +
  • 日期类型Java.Util.Date:${dateVar1?string('yyyy-MM-dd HH:mm:ss')}
  • +
  • 空值:${nullVar1!}
  • +
  • 空值:${nullVar!'我是默认值'}
  • +
  • 不存在的变量:${变量!'我是默认变量'}
  • +
  • 不存在的变量1:${free!'我是默认变量'}
  • +
+
+
    +
  • 赋值&运算
  • + <#assign a=100/> + a = ${a}
    + a+100=${a+100}
    +
+ + \ No newline at end of file diff --git a/spring-boot-20-Freemarker/src/main/resources/templates/free2.html b/spring-boot-20-Freemarker/src/main/resources/templates/free2.html new file mode 100644 index 0000000..24c033f --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/resources/templates/free2.html @@ -0,0 +1,64 @@ + + + + + freemarker + + + +

freemarker实现遍历list集合

+
    +
  • 集合list
  • + <#list programList as item> + ${item} + +
+
+

if表达式

+
    +
  • if : + <#assign var = 99/> + <#if var == 99> + var=99 + +
    + <#if var == 99> + var=99 + <#else/> + var!=99 + +
    + <#if var > 99> + var大于99 + <#elseif var==99/> + var=99 + <#else/> + var小于99 + +
  • + +
  • if多条件 ||,&&,! : + <#assign var='python'/> + <#if var =='python' || var =='Java'> + python or java
    + + <#if var =='python' && var?length == 6> + python length 6
    + + <#if (var =='python' && var?length == 6) || (var == 'java')> + python length 6或者Java

    + + <#if !((var =='python' && var?length == 6) || (var == 'java'))> + python length 6或者Java

    + +
  • +
+ + \ No newline at end of file diff --git a/spring-boot-20-Freemarker/src/main/resources/templates/free3.html b/spring-boot-20-Freemarker/src/main/resources/templates/free3.html new file mode 100644 index 0000000..e653414 --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/resources/templates/free3.html @@ -0,0 +1,71 @@ + + + + + freemarker + + + +

freemarker遍历map集合

+
    +
  • 集合map
  • + <#list map?keys as key> + ${key}:${map[key]}
    + +
+
+

switch语句

+
    +
  • switch,case,break,default
  • + <#assign var = 8/> + <#switch var> + <#case 1>星期一 + <#break/> + + <#case 2>星期二 + <#break/> + + <#case 3>星期三 + <#break/> + + <#case 4>星期四 + <#break/> + + <#case 5>星期五 + <#break/> + + <#case 6>星期六 + <#break/> + + <#case 7>星期日 + <#break/> + + <#default>无效的星期 + +
+
+
    +
  • switch,case,break,default
  • + <#assign var = 'java'/> + <#switch var> + <#case 'java'>我是java + <#break/> + + <#case 'python'>我是python + <#break/> + + <#case 'C'>我是C语言 + <#break/> + + <#default>我是谁?谁是我? + +
+ + \ No newline at end of file diff --git a/spring-boot-20-Freemarker/src/main/resources/templates/free4.html b/spring-boot-20-Freemarker/src/main/resources/templates/free4.html new file mode 100644 index 0000000..32cab75 --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/resources/templates/free4.html @@ -0,0 +1,101 @@ + + + + + freemarker + + + +

if表达式

+
    +
  • if
  • + <#assign var = 99/> + <#if var == 99> + var=99 + +
    + <#if var == 99> + var=99 + <#else> + var!=99 + + +
    + + <#if var > 99> + var大于99 + <#elseif var==99> + var=99 + <#else> + var小于99 + + + +
    + +
  • if多条件 ||,&&,!
  • + <#assign var='python'> + <#if var =='python' || var =='Java'> + python or java
    + + <#if var =='python' && var?length == 6> + python length 6
    + + <#if (var =='python' && var?length == 6) || (var == 'java')> + python length 6或者Java

    + + <#if !((var =='python' && var?length == 6) || (var == 'java'))> + python length 6或者Java

    + + +
+
+ +

自定义函数

+

1.自定义函数(整数排序sort_int)

+
    + <#assign myList=[2,5,9,1,0,6,3,1,10,4]/> +
  • 未排序
  • + <#list myList as item> + ${item}, + +
    +
  • 排序
  • + <#list sort_int(myList) as item> + ${item}, + +
+
+ +

List的指令

+

1,list常用指令sort升序

+
    + <#assign myList=[0,3,7,9,1,4,8,6,2,5]/> + <#list myList?sort as item> + ${item_index}:${item}
    + + +
    +
+
+ +

List的指令

+

2,list常用指令resverse倒序

+
    + <#assign myList1=[0,3,7,9,1,4,8,6,2,5]/> + <#list myList1?sort?reverse as item> + ${item_index}:${item}
    + + 长度:${myList1?size}
    + 下标取值:${myList1[3]}
    +
    +
+ + \ No newline at end of file diff --git a/spring-boot-20-Freemarker/src/main/resources/templates/free5.html b/spring-boot-20-Freemarker/src/main/resources/templates/free5.html new file mode 100644 index 0000000..862708f --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/resources/templates/free5.html @@ -0,0 +1,31 @@ + + + + + timebusker + + + +

自定义指令

+

1.用户123456 是否拥有admin角色,并且返回admin的权限

+
    + <@role user='123456' role='admin';result1,result2> + <#if result1> + 我的角色是admin
    + + 我拥有的权限是: + + <#list result2 as item> + ${item}, + + +
+ + \ No newline at end of file diff --git a/spring-boot-20-Freemarker/src/main/resources/templates/free6.html b/spring-boot-20-Freemarker/src/main/resources/templates/free6.html new file mode 100644 index 0000000..8a0f021 --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/resources/templates/free6.html @@ -0,0 +1,71 @@ + + + + +freemarker内建函数 + + + +

内建函数

+
    +

    1,字符串内建函数

    + <#list "a|b|c|d"?split("|") as item> +
  • ${item}
  • + +
+
+ +

字符串转日期

+
    + <#assign var1="23/02/2017" ?date("MM/dd/yyyy")/> + <#assign var2="11:34:33" ?time("HH:mm:ss")/> + <#assign var3="2017-02-23 11:35 PM" ?datetime("yyyy-MM-dd hh:mm")/> +
  • ${var1}
  • +
  • ${var2}
  • +
  • ${var3}
  • +
+
+ +

数字类型的内建函数

+
    + <#assign numVar1=314.5662789 /> +
  • 格式化:${numVar1?string("0.##")}
  • +
  • 四舍五入:${numVar1?round}
  • +
  • 去掉小数点:${numVar1?floor}
  • +
  • 进1:${numVar1?ceiling}
  • +
+
+ +

list内建函数

+
    + <#assign listVar1=[1,2,3,4,11,12,13,14,21,22,23,24] /> + +
  • 分块处理取长度:${listVar1?chunk(4)?size}
  • +
  • 长度:${listVar1?size}
  • + <#list listVar1?chunk(4)?last as item> +
  • ${item}
  • + +
  • 取list第一个值:${listVar1?first}
  • +
  • 取list最后一个值:${listVar1?last}
  • +
+
+ +

其他内建函数

+
    + <#assign sVar = 'helloworld'/> +
  • ${sVar?is_number?string('yes','no')}
  • +
  • ${sVar?has_content?string('yes','no')}
  • +
  • ${"1"+"2"?eval}
  • +
  • ${(1+2)?eval}
  • +
  • ${"1"+"2"?is_string?string('yes','no')}
  • +
  • ${("1"+"2")?is_string?string('yes','no')}
  • +
+ + \ No newline at end of file diff --git a/spring-boot-20-Freemarker/src/main/resources/templates/free7.html b/spring-boot-20-Freemarker/src/main/resources/templates/free7.html new file mode 100644 index 0000000..6f45a5c --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/resources/templates/free7.html @@ -0,0 +1,87 @@ + + + + + FreeMarker + + + +

macro,nested,return:实战demo

+

1.macro:宏指令

+
    +
  • FreeMarker:无参数的macro
  • +
    + <#macro test> + 我是无参数的macro + + <@test/> +
    +
  • Freemarker2:有参数的macro
  • +
    + <#macro test param1 param2> + 我是有参数的macro,paeam1=${param1},param2=${param2} +
    + + <@test param1="java" param2="python"/> +
    +
  • Freemarker3:有参数的macro
  • +
    + <#macro test param1 param2="JavaScript"> + 我是有参数的macro,paeam1=${param1},param2=${param2} +
    + + <@test param1="java" param2="hello python"/> +
    +
  • Freemarker4:有多个参数的macro
  • +
    + <#macro test param1 param2="python" paramExt...> + 我是有参数的macro,paeam1=${param1},param2=${param2} +
    + ${paramExt['param3']} + ${paramExt['param4']} + + <@test param1="java" param2="python" param3="nodejs" param4="html"/> +
    +
+
+

2,nested

+
+
    + <#macro test param1="java"> + ${param1}
    + <#nested param1,"我的nested参数"/> +
    + + +
  • 调用
  • +
    + <@test param1="java";loopVar1,loopVar2> + hello ${loopVar1},${loopVar2}
    + <@test/> + + <@test param1="python"; loopVar1> + hello ${loopVar1}
    + <@test/> +
    +
+
+
+

3,函数

+
    + <#function doAdd param1 param2> + <#return param1+param2/> + +
  • 调用
  • +
    你好,我是调用${doAdd(100,100)}
    +
+
+
+ + \ No newline at end of file diff --git a/spring-boot-20-Freemarker/src/main/resources/templates/index.html b/spring-boot-20-Freemarker/src/main/resources/templates/index.html new file mode 100644 index 0000000..b639fa0 --- /dev/null +++ b/spring-boot-20-Freemarker/src/main/resources/templates/index.html @@ -0,0 +1,38 @@ + + + + + timebusker + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字符串常用内建函数
freemarker取值,插值,并做复制判断
freemarker实现遍历list集合
freemarker遍历map集合
if表达式,自定义函数
自定义指令
freemarker内建函数
macro,nested,return:实战demo
数据对象绑定
+ + \ No newline at end of file diff --git a/spring-boot-21-MultiDataSource/README.md b/spring-boot-21-MultiDataSource/README.md new file mode 100644 index 0000000..67c69d8 --- /dev/null +++ b/spring-boot-21-MultiDataSource/README.md @@ -0,0 +1,14 @@ +#### Spring-Boot多数据源 +使用JdbcTemplate和Spring-data-jpa时,都使用了单数据源。在单数据源的情况下,Spring Boot的配置非常简单, +只需要在application.properties文件中配置连接参数即可。但是往往随着业务量发展,我们通常会进行数据库拆分或是引入其他数据库, +从而我们需要配置多个数据源。 + +#### 多数据源配置使用的核心是根据配置文件,初始化特定数据源,并绑定到特定的数据服务层,(dao、repository、mapper),因此 +spring-jdbc、Spring-data-jpa、Mybatis各自实现存在一定差异。其中多数据源又分静态数据源和动态数据源。 + +- 静态数据源:跨库使用数据库比较常用 +- 动态数据源:读写分离操作比较常用 + +##### [JdbcTemplate和Spring-data-jpa](https://www.cnblogs.com/fengmao/p/7538854.html) +##### [Spring Boot 集成Mybatis实现多数据源](https://blog.csdn.net/maoyeqiu/article/details/74011626) +##### [Spring Boot 集成Mybatis实现多数据源](https://blog.csdn.net/neosmith/article/details/61202084) diff --git a/spring-boot-21-MultiDataSource/pom.xml b/spring-boot-21-MultiDataSource/pom.xml new file mode 100644 index 0000000..6a682bd --- /dev/null +++ b/spring-boot-21-MultiDataSource/pom.xml @@ -0,0 +1,47 @@ + + + + spring-boot + cn.timebusker + 2.0.0 + + 4.0.0 + + spring-boot-21-MultiDataSource + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-logging + + + org.springframework.boot + spring-boot-starter-jetty + + + org.springframework.boot + spring-boot-starter-test + test + + + com.alibaba + fastjson + 1.2.31 + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + mysql + mysql-connector-java + + + \ No newline at end of file diff --git a/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/App.java b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/App.java new file mode 100644 index 0000000..4981b9f --- /dev/null +++ b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/App.java @@ -0,0 +1,17 @@ +package com.timebusker; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @DESC:Application + * @author:timebusker + * @date:2018/7/7 + */ +@SpringBootApplication +public class App { + + public static void main(String[] args) { + SpringApplication.run(App.class, args); + } +} diff --git a/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/cfg/KmDataSourceConfig.java b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/cfg/KmDataSourceConfig.java new file mode 100644 index 0000000..55931b7 --- /dev/null +++ b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/cfg/KmDataSourceConfig.java @@ -0,0 +1,62 @@ +package com.timebusker.cfg; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; + +/** + * @DESC:DataSourceConfig + * @author:timebusker + * @date:2018/7/7 + */ +@Configuration +@EnableTransactionManagement +@EnableJpaRepositories( + entityManagerFactoryRef = "kmEntityManagerFactory", + transactionManagerRef = "kmTransactionManager", + basePackages = {"com.timebusker.repository.km"} +) +public class KmDataSourceConfig { + + @Autowired + private JpaProperties jpaProperties; + + @Primary + @Bean(name = "kmDataSource") + @ConfigurationProperties(prefix = "km.spring.datasource") + public DataSource dataSource() { + return DataSourceBuilder.create().build(); + } + + @Primary + @Bean(name = "kmEntityManagerFactory") + public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("kmDataSource") DataSource kmDataSource) { + return builder + .dataSource(kmDataSource) + .packages("com.timebusker.entity.km") + .properties(jpaProperties.) + .persistenceUnit("test") + .build(); + } + + @Primary + @Bean(name = "kmTransactionManager") + public PlatformTransactionManager transactionManager(@Qualifier("kmEntityManagerFactory") EntityManagerFactory kmEntityManagerFactory) { + return new JpaTransactionManager(kmEntityManagerFactory); + } + +} diff --git a/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/cfg/QjDataSourceConfig.java b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/cfg/QjDataSourceConfig.java new file mode 100644 index 0000000..9be4382 --- /dev/null +++ b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/cfg/QjDataSourceConfig.java @@ -0,0 +1,57 @@ +package com.timebusker.cfg; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; +import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; +import org.springframework.context.annotation.*; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; + +/** + * @DESC:DataSourceConfig + * @author:timebusker + * @date:2018/7/7 + */ +@Configuration +@EnableTransactionManagement +@EnableJpaRepositories( + entityManagerFactoryRef = "qjEntityManagerFactory", + transactionManagerRef = "qjTransactionManager", + basePackages = {"com.timebusker.repository.qj"} +) +public class QjDataSourceConfig { + + @Autowired + private JpaProperties jpaProperties; + + @Bean(name = "qjDataSource") + @ConfigurationProperties(prefix = "qj.spring.datasource") + public DataSource otherDataSource() { + return DataSourceBuilder.create().build(); + } + + @Bean(name = "qjEntityManagerFactory") + public LocalContainerEntityManagerFactoryBean otherEntityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("qjDataSource") DataSource qjDataSource) { + return builder + .dataSource(qjDataSource) + .packages("com.timebusker.entity.qj") + .properties(jpaProperties.getHibernateProperties(qjDataSource)) + .persistenceUnit("qj") + .build(); + } + + @Bean(name = "qjTransactionManager") + public PlatformTransactionManager otherTransactionManager( + @Qualifier("qjEntityManagerFactory") EntityManagerFactory qjEntityManagerFactory) { + return new JpaTransactionManager(qjEntityManagerFactory); + } +} diff --git a/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/entity/km/SubInfoPo.java b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/entity/km/SubInfoPo.java new file mode 100644 index 0000000..033d6e3 --- /dev/null +++ b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/entity/km/SubInfoPo.java @@ -0,0 +1,265 @@ +package com.timebusker.entity.km; + +import javax.persistence.*; +import java.io.Serializable; +import java.util.Date; + +@Entity +@Table(name = "TB_SUB_INFO") +public class SubInfoPo implements Serializable{ + + @Id + @Column(name = "SUB_ID", nullable = false, length = 50) + private String subId; + + @Column(name = "REF_SUB_ID", nullable = false, length = 50) + private String refSubId; + + @Column(name = "SUB_NAME", nullable = true, length = 50) + private String subName; + + @Column(name = "REF_SUB_NAME", nullable = true, length = 50) + private String refSubName; + + @Column(name = "SUB_ENABLE", nullable = false) + private int subEnable; + + @Column(name = "SUB_EXEC_CLASS", nullable = false, length = 100) + private String subExeClass; + + @Column(name = "SUB_RESULT_TABLE", nullable = true, length = 100) + private String subResultTable; + + @Column(name = "SUB_DETAIL_TABLE", nullable = true, length = 100) + private String subDetailTable; + + @Column(name = "SUB_EXEC_TIME", nullable = true, length = 50) + private String subExecTime; + + @Column(name = "REPEAT_INTERVAL", nullable = true) + private int repeatInterval; + + @Column(name = "LAST_SUCCESS_BATCH", nullable = true, length = 50) + private String lastSuccessBatch; + + @Column(name = "LAST_SUCCESS_DATE", nullable = true) + private Date lastSuccessDate; + + @Column(name = "LAST_SUCCESS_ROWS", nullable = true) + private long lastSuccessRows; + + @Column(name = "EXEC_STATUS", nullable = true, length = 50) + private String execStatus; + + @Column(name = "MEMO", nullable = true, length = 500) + private String memo; + + @Column(name = "IS_RECOVER_EXE", nullable = true) + private int isRecoverExe; + + @Transient + private String status; + + @Column(name = "SUB_TYPE", nullable = true, length = 50) + private String subType; + + @Column(name = "SUB_AREANAME", nullable = true, length = 50) + private String subAreaname; + + @Column(name = "SUB_LEVEL", nullable = true) + private int subLevel; + + @Column(name = "DATA_SOURCE", nullable = true, length = 50) + private String dataSource; + + @Column(name = "ZT_TYPE", nullable = true, length = 50) + private String ztType; + + public String getSubType() { + return subType; + } + + public void setSubType(String subType) { + this.subType = subType; + } + + public String getSubAreaname() { + return subAreaname; + } + + public void setSubAreaname(String subAreaname) { + this.subAreaname = subAreaname; + } + + public int getSubLevel() { + return subLevel; + } + + public void setSubLevel(int subLevel) { + this.subLevel = subLevel; + } + + public String getDataSource() { + return dataSource; + } + + public void setDataSource(String dataSource) { + this.dataSource = dataSource; + } + + public String getSubId() { + return subId; + } + + public void setSubId(String subId) { + this.subId = subId; + } + + public String getRefSubId() { + return refSubId; + } + + public void setRefSubId(String refSubId) { + this.refSubId = refSubId; + } + + public String getSubName() { + return subName; + } + + public void setSubName(String subName) { + this.subName = subName; + } + + public String getRefSubName() { + return refSubName; + } + + public void setRefSubName(String refSubName) { + this.refSubName = refSubName; + } + + public int getSubEnable() { + return subEnable; + } + + public void setSubEnable(int subEnable) { + this.subEnable = subEnable; + } + + public String getSubExeClass() { + return subExeClass; + } + + public void setSubExeClass(String subExeClass) { + this.subExeClass = subExeClass; + } + + public String getSubResultTable() { + return subResultTable; + } + + public void setSubResultTable(String subResultTable) { + this.subResultTable = subResultTable; + } + + public String getSubDetailTable() { + return subDetailTable; + } + + public void setSubDetailTable(String subDetailTable) { + this.subDetailTable = subDetailTable; + } + + public String getSubExecTime() { + return subExecTime; + } + + public void setSubExecTime(String subExecTime) { + this.subExecTime = subExecTime; + } + + public int getRepeatInterval() { + return repeatInterval; + } + + public void setRepeatInterval(int repeatInterval) { + this.repeatInterval = repeatInterval; + } + + public String getLastSuccessBatch() { + return lastSuccessBatch; + } + + public void setLastSuccessBatch(String lastSuccessBatch) { + this.lastSuccessBatch = lastSuccessBatch; + } + + public Date getLastSuccessDate() { + return lastSuccessDate; + } + + public void setLastSuccessDate(Date lastSuccessDate) { + this.lastSuccessDate = lastSuccessDate; + } + + public long getLastSuccessRows() { + return lastSuccessRows; + } + + public void setLastSuccessRows(long lastSuccessRows) { + this.lastSuccessRows = lastSuccessRows; + } + + public String getExecStatus() { + return execStatus; + } + + public void setExecStatus(String execStatus) { + this.execStatus = execStatus; + } + + public String getMemo() { + return memo; + } + + public void setMemo(String memo) { + this.memo = memo; + } + + public int getIsRecoverExe() { + return isRecoverExe; + } + + public void setIsRecoverExe(int isRecoverExe) { + this.isRecoverExe = isRecoverExe; + } + + public String getStatus() { + return this.status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getZtType() { + return ztType; + } + + public void setZtType(String yskType) { + this.ztType = yskType; + } + + @Override + public String toString() { + return "SubInfoPo [subId=" + subId + ", refSubId=" + refSubId + ", subName=" + subName + ", refSubName=" + refSubName + ", subEnable=" + subEnable + + ", subExeClass=" + subExeClass + ", subResultTable=" + subResultTable + ", subDetailTable=" + subDetailTable + ", subExecTime=" + subExecTime + + ", repeatInterval=" + repeatInterval + ", lastSuccessBatch=" + lastSuccessBatch + ", lastSuccessDate=" + lastSuccessDate + + ", lastSuccessRows=" + lastSuccessRows + ", execStatus=" + execStatus + ", memo=" + memo + ", status=" + status + "]"; + } + + public SubInfoPo() { + + } +} diff --git a/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/entity/km/TbSubExpTask.java b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/entity/km/TbSubExpTask.java new file mode 100644 index 0000000..e4ce66d --- /dev/null +++ b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/entity/km/TbSubExpTask.java @@ -0,0 +1,120 @@ +package com.timebusker.entity.km; + +import javax.persistence.*; +import java.io.Serializable; + +/** + * TbSubExpTask entity + */ +@Entity +@Table(name = "TB_SUB_EXP_TASK") +public class TbSubExpTask implements Serializable { + + private static final long serialVersionUID = 1117632073865779512L; + private String id; + private String subId; + private String batchId; + private String onlineDbType; + private String expStatus; + private String addTime; + private String exportTime; + private String expTable; + private Integer isDirect; + + /** + * default constructor + */ + public TbSubExpTask() { + } + + /** + * minimal constructor + */ + public TbSubExpTask(String id) { + this.id = id; + } + + // Property accessors + @Id + @Column(name = "ID", unique = true, nullable = false, length = 50) + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + @Column(name = "SUB_ID", length = 50) + public String getSubId() { + return this.subId; + } + + public void setSubId(String subId) { + this.subId = subId; + } + + @Column(name = "BATCH_ID", length = 50) + public String getBatchId() { + return this.batchId; + } + + public void setBatchId(String batchId) { + this.batchId = batchId; + } + + @Column(name = "EXP_STATUS", length = 4000) + public String getExpStatus() { + return this.expStatus; + } + + public void setExpStatus(String expStatus) { + this.expStatus = expStatus; + } + + @Column(name = "ADD_TIME", length = 20) + public String getAddTime() { + return this.addTime; + } + + public void setAddTime(String addTime) { + this.addTime = addTime; + } + + @Column(name = "EXPORT_TIME", length = 20) + public String getExportTime() { + return this.exportTime; + } + + public void setExportTime(String exportTime) { + this.exportTime = exportTime; + } + + @Column(name = "EXP_TABLE", length = 100) + public String getExpTable() { + return this.expTable; + } + + public void setExpTable(String expTable) { + this.expTable = expTable; + } + + @Column(name = "ONLINE_DB_TYPE", length = 30) + public String getOnlineDbType() { + return onlineDbType; + } + + public void setOnlineDbType(String onlineDbType) { + this.onlineDbType = onlineDbType; + } + + @Column(name = "IS_DIRECT", precision = 0) + public Integer getIsDirect() { + return isDirect; + } + + public void setIsDirect(Integer isDirect) { + this.isDirect = isDirect; + } + +} \ No newline at end of file diff --git a/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/entity/km/TbSubExport.java b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/entity/km/TbSubExport.java new file mode 100644 index 0000000..97474ff --- /dev/null +++ b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/entity/km/TbSubExport.java @@ -0,0 +1,246 @@ +package com.timebusker.entity.km; + + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import java.io.Serializable; + +/** + * TbSubExportT entity. @author MyEclipse Persistence Tools + */ +@Entity +@Table(name = "TB_SUB_EXPORT") +public class TbSubExport implements Serializable { + + + private static final long serialVersionUID = -6410050652407144204L; + private String id; + private String subId; + private String onlineDbType; + private Integer exportEnable; + private Integer combileWay; + private String hiveTable; + private String exportTable; + private String exportPath; + private String hiveCols; + private String hiveWhere; + private String mppDiscol; + private Integer mppExpmod; + private String orclOption; + private Integer orclDirect; + private Integer orclSqlldrNums; + private Integer icpMapNum; + private String partitionCol; + private Integer icpShardNum; + private String icpIndexs; + private Integer icpExportOrc; + private Integer isDirect; + private String isBigTable; + + + @Id + @Column(name = "ID", nullable = false, length = 36) + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Column(name = "SUB_ID", length = 50) + public String getSubId() { + return this.subId; + } + + public void setSubId(String subId) { + this.subId = subId; + } + + @Column(name = "ONLINE_DB_TYPE", length = 30) + public String getOnlineDbType() { + return this.onlineDbType; + } + + public void setOnlineDbType(String onlineDbType) { + this.onlineDbType = onlineDbType; + } + + @Column(name = "EXPORT_ENABLE") + public Integer getExportEnable() { + return this.exportEnable; + } + + public void setExportEnable(Integer exportEnable) { + this.exportEnable = exportEnable; + } + + @Column(name = "COMBILE_WAY") + public Integer getCombileWay() { + return combileWay; + } + + public void setCombileWay(Integer combileWay) { + this.combileWay = combileWay; + } + + @Column(name = "HIVE_TABLE", length = 30) + public String getHiveTable() { + return this.hiveTable; + } + + public void setHiveTable(String hiveTable) { + this.hiveTable = hiveTable; + } + + @Column(name = "EXPORT_TABLE", length = 30) + public String getExportTable() { + return this.exportTable; + } + + public void setExportTable(String exportTable) { + this.exportTable = exportTable; + } + + @Column(name = "EXPORT_PATH", length = 50) + public String getExportPath() { + return this.exportPath; + } + + public void setExportPath(String exportPath) { + this.exportPath = exportPath; + } + + @Column(name = "HIVE_COLS", length = 300) + public String getHiveCols() { + return this.hiveCols; + } + + public void setHiveCols(String hiveCols) { + this.hiveCols = hiveCols; + } + + @Column(name = "HIVE_WHERE", length = 300) + public String getHiveWhere() { + return this.hiveWhere; + } + + public void setHiveWhere(String hiveWhere) { + this.hiveWhere = hiveWhere; + } + + @Column(name = "MPP_DISCOL", length = 100) + public String getMppDiscol() { + return this.mppDiscol; + } + + public void setMppDiscol(String mppDiscol) { + this.mppDiscol = mppDiscol; + } + + @Column(name = "MPP_EXPMOD") + public Integer getMppExpmod() { + return this.mppExpmod; + } + + public void setMppExpmod(Integer mppExpmod) { + this.mppExpmod = mppExpmod; + } + + @Column(name = "ORCL_OPTION", length = 100) + public String getOrclOption() { + return this.orclOption; + } + + public void setOrclOption(String orclOption) { + this.orclOption = orclOption; + } + + @Column(name = "ORCL_DIRECT") + public Integer getOrclDirect() { + return this.orclDirect; + } + + public void setOrclDirect(Integer orclDirect) { + this.orclDirect = orclDirect; + } + + @Column(name = "ORCL_SQLLDR_NUMS") + public Integer getOrclSqlldrNums() { + return this.orclSqlldrNums; + } + + public void setOrclSqlldrNums(Integer orclSqlldrNums) { + this.orclSqlldrNums = orclSqlldrNums; + } + + + @Column(name = "ICP_MAP_NUM") + public Integer getIcpMapNum() { + return this.icpMapNum; + } + + public void setIcpMapNum(Integer icpMapNum) { + this.icpMapNum = icpMapNum; + } + + @Column(name = "PARTITION_COL", length = 20) + public String getPartitionCol() { + return partitionCol; + } + + public void setPartitionCol(String partitionCol) { + this.partitionCol = partitionCol; + } + + + @Column(name = "ICP_SHARD_NUM") + public Integer getIcpShardNum() { + return icpShardNum; + } + + public void setIcpShardNum(Integer icpShardNum) { + this.icpShardNum = icpShardNum; + } + + @Column(name = "ICP_INDEXS", length = 100) + public String getIcpIndexs() { + return icpIndexs; + } + + public void setIcpIndexs(String icpIndexs) { + this.icpIndexs = icpIndexs; + } + + + @Column(name = "IS_DIRECT", precision = 0) + public Integer getIsDirect() { + return isDirect; + } + + public void setIsDirect(Integer isDirect) { + this.isDirect = isDirect; + + } + + @Column(name = "IS_BIG_TABLE", precision = 0) + public String getIsBigTable() { + return isBigTable; + } + + public void setIsBigTable(String isBigTable) { + this.isBigTable = isBigTable; + } + + + @Column(name = "ICP_EXPORT_ORC") + public Integer getIcpExportOrc() { + return icpExportOrc; + } + + public void setIcpExportOrc(Integer icpExportOrc) { + this.icpExportOrc = icpExportOrc; + } +} \ No newline at end of file diff --git a/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/entity/qj/SubInfoPo.java b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/entity/qj/SubInfoPo.java new file mode 100644 index 0000000..9670f39 --- /dev/null +++ b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/entity/qj/SubInfoPo.java @@ -0,0 +1,265 @@ +package com.timebusker.entity.qj; + +import javax.persistence.*; +import java.io.Serializable; +import java.util.Date; + +@Entity +@Table(name = "TB_SUB_INFO") +public class SubInfoPo implements Serializable{ + + @Id + @Column(name = "SUB_ID", nullable = false, length = 50) + private String subId; + + @Column(name = "REF_SUB_ID", nullable = false, length = 50) + private String refSubId; + + @Column(name = "SUB_NAME", nullable = true, length = 50) + private String subName; + + @Column(name = "REF_SUB_NAME", nullable = true, length = 50) + private String refSubName; + + @Column(name = "SUB_ENABLE", nullable = false) + private int subEnable; + + @Column(name = "SUB_EXEC_CLASS", nullable = false, length = 100) + private String subExeClass; + + @Column(name = "SUB_RESULT_TABLE", nullable = true, length = 100) + private String subResultTable; + + @Column(name = "SUB_DETAIL_TABLE", nullable = true, length = 100) + private String subDetailTable; + + @Column(name = "SUB_EXEC_TIME", nullable = true, length = 50) + private String subExecTime; + + @Column(name = "REPEAT_INTERVAL", nullable = true) + private int repeatInterval; + + @Column(name = "LAST_SUCCESS_BATCH", nullable = true, length = 50) + private String lastSuccessBatch; + + @Column(name = "LAST_SUCCESS_DATE", nullable = true) + private Date lastSuccessDate; + + @Column(name = "LAST_SUCCESS_ROWS", nullable = true) + private long lastSuccessRows; + + @Column(name = "EXEC_STATUS", nullable = true, length = 50) + private String execStatus; + + @Column(name = "MEMO", nullable = true, length = 500) + private String memo; + + @Column(name = "IS_RECOVER_EXE", nullable = true) + private int isRecoverExe; + + @Transient + private String status; + + @Column(name = "SUB_TYPE", nullable = true, length = 50) + private String subType; + + @Column(name = "SUB_AREANAME", nullable = true, length = 50) + private String subAreaname; + + @Column(name = "SUB_LEVEL", nullable = true) + private int subLevel; + + @Column(name = "DATA_SOURCE", nullable = true, length = 50) + private String dataSource; + + @Column(name = "ZT_TYPE", nullable = true, length = 50) + private String ztType; + + public String getSubType() { + return subType; + } + + public void setSubType(String subType) { + this.subType = subType; + } + + public String getSubAreaname() { + return subAreaname; + } + + public void setSubAreaname(String subAreaname) { + this.subAreaname = subAreaname; + } + + public int getSubLevel() { + return subLevel; + } + + public void setSubLevel(int subLevel) { + this.subLevel = subLevel; + } + + public String getDataSource() { + return dataSource; + } + + public void setDataSource(String dataSource) { + this.dataSource = dataSource; + } + + public String getSubId() { + return subId; + } + + public void setSubId(String subId) { + this.subId = subId; + } + + public String getRefSubId() { + return refSubId; + } + + public void setRefSubId(String refSubId) { + this.refSubId = refSubId; + } + + public String getSubName() { + return subName; + } + + public void setSubName(String subName) { + this.subName = subName; + } + + public String getRefSubName() { + return refSubName; + } + + public void setRefSubName(String refSubName) { + this.refSubName = refSubName; + } + + public int getSubEnable() { + return subEnable; + } + + public void setSubEnable(int subEnable) { + this.subEnable = subEnable; + } + + public String getSubExeClass() { + return subExeClass; + } + + public void setSubExeClass(String subExeClass) { + this.subExeClass = subExeClass; + } + + public String getSubResultTable() { + return subResultTable; + } + + public void setSubResultTable(String subResultTable) { + this.subResultTable = subResultTable; + } + + public String getSubDetailTable() { + return subDetailTable; + } + + public void setSubDetailTable(String subDetailTable) { + this.subDetailTable = subDetailTable; + } + + public String getSubExecTime() { + return subExecTime; + } + + public void setSubExecTime(String subExecTime) { + this.subExecTime = subExecTime; + } + + public int getRepeatInterval() { + return repeatInterval; + } + + public void setRepeatInterval(int repeatInterval) { + this.repeatInterval = repeatInterval; + } + + public String getLastSuccessBatch() { + return lastSuccessBatch; + } + + public void setLastSuccessBatch(String lastSuccessBatch) { + this.lastSuccessBatch = lastSuccessBatch; + } + + public Date getLastSuccessDate() { + return lastSuccessDate; + } + + public void setLastSuccessDate(Date lastSuccessDate) { + this.lastSuccessDate = lastSuccessDate; + } + + public long getLastSuccessRows() { + return lastSuccessRows; + } + + public void setLastSuccessRows(long lastSuccessRows) { + this.lastSuccessRows = lastSuccessRows; + } + + public String getExecStatus() { + return execStatus; + } + + public void setExecStatus(String execStatus) { + this.execStatus = execStatus; + } + + public String getMemo() { + return memo; + } + + public void setMemo(String memo) { + this.memo = memo; + } + + public int getIsRecoverExe() { + return isRecoverExe; + } + + public void setIsRecoverExe(int isRecoverExe) { + this.isRecoverExe = isRecoverExe; + } + + public String getStatus() { + return this.status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getZtType() { + return ztType; + } + + public void setZtType(String yskType) { + this.ztType = yskType; + } + + @Override + public String toString() { + return "SubInfoPo [subId=" + subId + ", refSubId=" + refSubId + ", subName=" + subName + ", refSubName=" + refSubName + ", subEnable=" + subEnable + + ", subExeClass=" + subExeClass + ", subResultTable=" + subResultTable + ", subDetailTable=" + subDetailTable + ", subExecTime=" + subExecTime + + ", repeatInterval=" + repeatInterval + ", lastSuccessBatch=" + lastSuccessBatch + ", lastSuccessDate=" + lastSuccessDate + + ", lastSuccessRows=" + lastSuccessRows + ", execStatus=" + execStatus + ", memo=" + memo + ", status=" + status + "]"; + } + + public SubInfoPo() { + + } +} diff --git a/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/repository/BaseRepository.java b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/repository/BaseRepository.java new file mode 100644 index 0000000..e501b27 --- /dev/null +++ b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/repository/BaseRepository.java @@ -0,0 +1,9 @@ +package com.timebusker.repository; + +import java.io.Serializable; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface BaseRepository extends JpaRepository{ + +} diff --git a/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/repository/km/KmSubExpTaskRepository.java b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/repository/km/KmSubExpTaskRepository.java new file mode 100644 index 0000000..9dddd4b --- /dev/null +++ b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/repository/km/KmSubExpTaskRepository.java @@ -0,0 +1,17 @@ +package com.timebusker.repository.km; + +import com.timebusker.entity.km.TbSubExpTask; +import com.timebusker.repository.BaseRepository; +import org.springframework.data.jpa.repository.Query; + +/** + * @DESC:SubExpTaskRepository + * @author:timebusker + * @date:2018/7/7 + */ +public interface KmSubExpTaskRepository extends BaseRepository { + + @Query("select count(t) from TbSubExpTask t where expStatus='OK' and subId=?1 and batchId=?2") + int getLastSubExpTask(String subId,String batchId); + +} diff --git a/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/repository/km/KmSubExportRepository.java b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/repository/km/KmSubExportRepository.java new file mode 100644 index 0000000..cd526c5 --- /dev/null +++ b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/repository/km/KmSubExportRepository.java @@ -0,0 +1,21 @@ +package com.timebusker.repository.km; + +import com.timebusker.entity.km.TbSubExport; +import com.timebusker.repository.BaseRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +/** + * @DESC:SubExpTaskRepository + * @author:timebusker + * @date:2018/7/7 + */ +public interface KmSubExportRepository extends BaseRepository { + + @Query("select subId from TbSubExport t where onlineDbType='HIVE-HIVE' and exportEnable=1 group by subId") + List getSubExportToHive(); + + @Query("select count(t) from TbSubExport t where onlineDbType='HIVE-HIVE' and exportEnable=1 and subId=?1") + int getSubExportToHiveCnt(String subId); +} diff --git a/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/repository/km/KmSubInfoRepository.java b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/repository/km/KmSubInfoRepository.java new file mode 100644 index 0000000..8461808 --- /dev/null +++ b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/repository/km/KmSubInfoRepository.java @@ -0,0 +1,16 @@ +package com.timebusker.repository.km; + +import com.timebusker.entity.km.SubInfoPo; +import com.timebusker.repository.BaseRepository; +import org.springframework.data.jpa.repository.Query; + +/** + * @DESC:SubInfoRepository + * @author:timebusker + * @date:2018/7/7 + */ +public interface KmSubInfoRepository extends BaseRepository { + + @Query("select t from SubInfoPo t where subEnable=1 and execStatus='OK' and subId=?1") + SubInfoPo getKmSubInfo(String subId); +} diff --git a/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/repository/qj/QjSubInfoRepository.java b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/repository/qj/QjSubInfoRepository.java new file mode 100644 index 0000000..4518fc9 --- /dev/null +++ b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/repository/qj/QjSubInfoRepository.java @@ -0,0 +1,12 @@ +package com.timebusker.repository.qj; + +import com.timebusker.entity.qj.SubInfoPo; +import com.timebusker.repository.BaseRepository; + +/** + * @DESC:SubInfoRepository + * @author:timebusker + * @date:2018/7/7 + */ +public interface QjSubInfoRepository extends BaseRepository { +} diff --git a/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/service/SyncSubInfoService.java b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/service/SyncSubInfoService.java new file mode 100644 index 0000000..221c765 --- /dev/null +++ b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/service/SyncSubInfoService.java @@ -0,0 +1,67 @@ +package com.timebusker.service; + +import com.timebusker.entity.km.SubInfoPo; +import com.timebusker.repository.km.*; +import com.timebusker.repository.qj.QjSubInfoRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +/** + * @DESC:SyncSubInfoService + * @author:timebusker + * @date:2018/7/7 + */ +@Service +public class SyncSubInfoService { + + private final static Long AFTER_TIME = 1800000L; + + @Autowired + private QjSubInfoRepository qjSubInfoRepository; + + @Autowired + private KmSubExportRepository kmSubExportRepository; + + @Autowired + private KmSubExpTaskRepository kmSubExpTaskRepository; + + @Autowired + private KmSubInfoRepository kmSubInfoRepository; + + public SubInfoPo getKmSubInfo(String subId) { + SubInfoPo sub = kmSubInfoRepository.getKmSubInfo(subId); + return sub; + } + + public int getLastSubExpTask(String subId, String batchId) { + int cnt = kmSubExpTaskRepository.getLastSubExpTask(subId, batchId); + return cnt; + } + + public int getSubExportToHiveCnt(String subId) { + int cnt = kmSubExportRepository.getSubExportToHiveCnt(subId); + return cnt; + } + + public List getSubExportToHive() { + List list = kmSubExportRepository.getSubExportToHive(); + return list; + } + + public void saveOrUpdateSubInfo(com.timebusker.entity.qj.SubInfoPo sub) { + qjSubInfoRepository.save(sub); + } + + private static Date getLastTime() { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Long lt = System.currentTimeMillis() - AFTER_TIME; + Date date = new Date(lt); + System.out.println(format.format(date)); + System.out.println(date); + return date; + } +} diff --git a/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/task/SyncSubInfoTask.java b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/task/SyncSubInfoTask.java new file mode 100644 index 0000000..785088c --- /dev/null +++ b/spring-boot-21-MultiDataSource/src/main/java/com/timebusker/task/SyncSubInfoTask.java @@ -0,0 +1,92 @@ +package com.timebusker.task; + +import com.alibaba.fastjson.JSON; +import com.timebusker.entity.km.SubInfoPo; +import com.timebusker.service.SyncSubInfoService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; + +import java.util.*; + +/** + * @DESC:SyncSubInfoTask + * @author:timebusker + * @date:2018/7/7 + */ +@Configuration +@EnableScheduling +public class SyncSubInfoTask { + + private static final Logger log = LoggerFactory.getLogger(SyncSubInfoTask.class); + + private static final Map submap = new HashMap<>(); + + @Autowired + private SyncSubInfoService syncSubInfoService; + + @Scheduled(cron = "0/20 * * * * *") + public void task1() { + log.info("开始同步数据!"); + // 查询需导出数据到HIVE的列表 + List list = syncSubInfoService.getSubExportToHive(); + log.info("需要同步专题有:" + JSON.toJSONString(list)); + for (String subid : list) { + // 查询当前成功批次 + SubInfoPo subkm = syncSubInfoService.getKmSubInfo(subid); + if (null != submap.get(subkm.getSubId()) && subkm.getLastSuccessBatch().equals(submap.get(subkm.getSubId()))) { + continue; + } else { + if (null != submap.get(subkm.getSubId())) { + submap.replace(subkm.getSubId(), subkm.getLastSuccessBatch()); + } else { + submap.put(subkm.getSubId(), subkm.getLastSuccessBatch()); + } + } + int task = syncSubInfoService.getLastSubExpTask(subkm.getSubId(), subkm.getLastSuccessBatch()); + int exp = syncSubInfoService.getSubExportToHiveCnt(subkm.getSubId()); + // 全部导出成功 + if (task == exp) { + log.info("当前同专题:" + subkm.getSubName() + "\t" + subkm.getSubId() + "\t" + subkm.getLastSuccessBatch()); + com.timebusker.entity.qj.SubInfoPo sub = new com.timebusker.entity.qj.SubInfoPo(); + sub.setDataSource(subkm.getDataSource()); + sub.setExecStatus(subkm.getExecStatus()); + sub.setIsRecoverExe(subkm.getIsRecoverExe()); + sub.setLastSuccessBatch(subkm.getLastSuccessBatch()); + sub.setLastSuccessDate(subkm.getLastSuccessDate()); + sub.setLastSuccessRows(subkm.getLastSuccessRows()); + sub.setMemo(subkm.getMemo()); + sub.setRefSubId(subkm.getRefSubId()); + sub.setRefSubName(subkm.getRefSubName()); + sub.setRepeatInterval(subkm.getRepeatInterval()); + sub.setStatus(subkm.getStatus()); + sub.setSubAreaname(subkm.getSubAreaname()); + sub.setSubDetailTable(subkm.getSubDetailTable()); + sub.setSubEnable(0); + sub.setSubExeClass(subkm.getSubExeClass()); + sub.setSubExecTime(subkm.getSubExecTime()); + sub.setSubId(subkm.getSubId()); + sub.setSubLevel(subkm.getSubLevel()); + sub.setSubName(subkm.getSubName()); + sub.setSubResultTable(subkm.getSubResultTable()); + sub.setSubType(subkm.getSubType()); + sub.setZtType(subkm.getZtType()); + syncSubInfoService.saveOrUpdateSubInfo(sub); + log.info("同步成功:" + subkm.getSubName() + "\t" + subkm.getSubId() + "\t" + subkm.getLastSuccessBatch()); + } + } + } + +// public static void main(String[] args) { +// Map smap = new HashMap<>(); +// smap.put("1", "1"); +// smap.put("2", "2"); +// System.out.println(smap.get("3")); +// smap.replace("1", "a"); +// smap.put("11", "11"); +// System.out.println(JSON.toJSONString(smap)); +// } +} diff --git a/spring-boot-21-MultiDataSource/src/main/resources/application.properties b/spring-boot-21-MultiDataSource/src/main/resources/application.properties new file mode 100644 index 0000000..7d3c3bc --- /dev/null +++ b/spring-boot-21-MultiDataSource/src/main/resources/application.properties @@ -0,0 +1,44 @@ +# \u9879\u76EEcontextPath\uFF0C\u4E00\u822C\u5728\u6B63\u5F0F\u53D1\u5E03\u7248\u672C\u4E2D\uFF0C\u6211\u4EEC\u4E0D\u914D\u7F6E +server.context-path=/ +# \u9519\u8BEF\u9875\uFF0C\u6307\u5B9A\u53D1\u751F\u9519\u8BEF\u65F6\uFF0C\u8DF3\u8F6C\u7684URL\u3002\u8BF7\u67E5\u770BBasicErrorController\u6E90\u7801\u4FBF\u77E5 +server.error.path=/error +# \u670D\u52A1\u7AEF\u53E3 +server.port=0 +# session\u6700\u5927\u8D85\u65F6\u65F6\u95F4(\u5206\u949F)\uFF0C\u9ED8\u8BA4\u4E3A30 +server.session-timeout=60 +# \u8BE5\u670D\u52A1\u7ED1\u5B9AIP\u5730\u5740\uFF0C\u542F\u52A8\u670D\u52A1\u5668\u65F6\u5982\u672C\u673A\u4E0D\u662F\u8BE5IP\u5730\u5740\u5219\u629B\u51FA\u5F02\u5E38\u542F\u52A8\u5931\u8D25\uFF0C\u53EA\u6709\u7279\u6B8A\u9700\u6C42\u7684\u60C5\u51B5\u4E0B\u624D\u914D\u7F6E +# server.address=192.168.16.11 +######################################################## +### datasource ,mysql\u6570\u636E\u5E93\u8FDE\u63A5\u914D\u7F6E +######################################################## +km.spring.datasource.url=jdbc:mysql://mysql.db.server:3306/db1?useUnicode=true&characterEncoding=utf-8&useSSL=true&autoReconnect=true +km.spring.datasource.username=root +km.spring.datasource.password=timebusker +km.spring.datasource.driver-class-name=com.mysql.jdbc.Driver +qj.spring.datasource.url=jdbc:mysql://mysql.db.server:3306/db2?useUnicode=true&characterEncoding=utf-8&useSSL=true&autoReconnect=true +qj.spring.datasource.username=root +qj.spring.datasource.password=timebusker +qj.spring.datasource.driver-class-name=com.mysql.jdbc.Driver +######################################################## +### Java Persistence Api \uFF0CJPA\u81EA\u52A8\u5EFA\u8868\u64CD\u4F5C\u914D\u7F6E +######################################################## +# Specify the DBMS +spring.jpa.database=MYSQL +# Show or not log for each sql query +spring.jpa.show-sql=true +# Hibernate ddl auto (create, create-drop, update,validate) +spring.jpa.hibernate.ddl-auto=update +# stripped before adding them to the entity manager) +spring.jpa.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect +######################################################## +### \u8FDE\u63A5\u6C60\u914D\u7F6E +######################################################## +spring.datasource.maximum-pool-size=100 +spring.datasource.max-idle=10 +spring.datasource.max-wait=10000 +spring.datasource.min-idle=1 +spring.datasource.initial-size=1 +spring.datasource.validation-query=SELECT 1 +spring.datasource.test-on-borrow=false +spring.datasource.test-while-idle=true +spring.datasource.time-between-eviction-runs-millis=18800 \ No newline at end of file diff --git a/spring-boot-21-MultiDataSource/src/main/resources/logback.xml b/spring-boot-21-MultiDataSource/src/main/resources/logback.xml new file mode 100644 index 0000000..710e2be --- /dev/null +++ b/spring-boot-21-MultiDataSource/src/main/resources/logback.xml @@ -0,0 +1,12 @@ + + + + + %msg%n + + + + + + + diff --git a/spring-boot-22-FarstPlus/pom.xml b/spring-boot-22-FarstPlus/pom.xml new file mode 100644 index 0000000..ec068a3 --- /dev/null +++ b/spring-boot-22-FarstPlus/pom.xml @@ -0,0 +1,151 @@ + + + + spring-boot + cn.timebusker + 2.0.0 + + 4.0.0 + + spring-boot-22-FarstPlus + + + ${artifactId}-${version} + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + + UTF-8 + UTF-8 + 1.8 + + 0.0.9 + 1.3.2 + 1.2.31 + 2.6 + 1.3.1 + 2.5 + 1.10 + 1.10 + + /work/renren + ${artifactId}-${version}.jar + 192.168.1.10:22 + root + 123456 + + + + + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + + org.springframework.boot + spring-boot-starter-jetty + + + + org.springframework.boot + spring-boot-starter-freemarker + + + + commons-lang + commons-lang + ${commons.lang.version} + + + commons-fileupload + commons-fileupload + ${commons.fileupload.version} + + + commons-io + commons-io + ${commons.io.version} + + + commons-codec + commons-codec + ${commons.codec.version} + + + commons-configuration + commons-configuration + ${commons.configuration.version} + + + + com.github.axet + kaptcha + ${kaptcha.version} + + + + com.alibaba + fastjson + ${fastjson.version} + + + + com.rabbitmq + http-client + 1.0.0.RELEASE + + + + + org.apache.shiro + shiro-core + ${shiro.version} + + + org.apache.shiro + shiro-spring + ${shiro.version} + + + + \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/App.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/App.java new file mode 100644 index 0000000..ecbba3b --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/App.java @@ -0,0 +1,20 @@ +package com.timebusker; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @DESC:Application + * @author:timebusker + * @date:2018/8/22 + */ +@SpringBootApplication +public class App { + + public static void main(String[] args) { + SpringApplication.run(App.class); + System.err.println("\n**************************************\n"); + System.err.println("\t\t\t服务启动成功..."); + System.err.println("\n**************************************\n"); + } +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/WebFilterConfig.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/WebFilterConfig.java new file mode 100644 index 0000000..638457f --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/WebFilterConfig.java @@ -0,0 +1,41 @@ +package com.timebusker; + +import com.timebusker.utils.LoginFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.filter.DelegatingFilterProxy; + +import javax.servlet.DispatcherType; + +/** + * @DESC:WebFilterConfig:Filter配置 + * @author:timebusker + * @date:2018/8/23 + */ +@Configuration +public class WebFilterConfig { + +// @Bean +// public FilterRegistrationBean shiroFilterRegistration() { +// FilterRegistrationBean registration = new FilterRegistrationBean(); +// registration.setFilter(new DelegatingFilterProxy("shiroFilter")); +// //该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 +// registration.addInitParameter("targetFilterLifecycle", "true"); +// registration.setEnabled(true); +// registration.setOrder(Integer.MIN_VALUE); +// registration.addUrlPatterns("/*"); +// return registration; +// } + + @Bean + public FilterRegistrationBean xssFilterRegistration() { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setDispatcherTypes(DispatcherType.REQUEST); + registration.setFilter(new LoginFilter()); + registration.addUrlPatterns("/*"); + registration.setName("xssFilter"); + registration.setOrder(Integer.MAX_VALUE); + return registration; + } +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/WebKaptchaConfig.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/WebKaptchaConfig.java new file mode 100644 index 0000000..33aa81f --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/WebKaptchaConfig.java @@ -0,0 +1,43 @@ +package com.timebusker; + +import com.google.code.kaptcha.impl.DefaultKaptcha; +import com.google.code.kaptcha.util.Config; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Properties; + +/** + * @DESC:WebKaptchaConfig:生成验证码配置 + * @author:timebusker + * @date:2018/8/22 + */ +@Configuration +public class WebKaptchaConfig { + + @Bean + public DefaultKaptcha producer() { + // http://blog.csdn.net/xiaokui_wingfly/article/details/41744887 + Properties properties = new Properties(); + // 图片边框,合法值:yes , no + properties.put("kaptcha.border", "no"); + // kaptcha.image.width 图片宽 200 + // kaptcha.image.height 图片高 50 + // kaptcha.producer.impl 图片实现类 com.google.code.kaptcha.impl.DefaultKaptcha + // kaptcha.textproducer.impl 文本实现类 com.google.code.kaptcha.text.impl.DefaultTextCreator + // kaptcha.background.clear.from 背景颜色渐变,开始颜色 light grey + // kaptcha.background.clear.to 背景颜色渐变,结束颜色 white + properties.put("kaptcha.textproducer.font.color", "gray"); + properties.put("kaptcha.background.clear.from", "gray"); + properties.put("kaptcha.background.clear.to", "white"); + properties.put("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.ShadowGimpy"); + properties.put("kaptcha.textproducer.char.space", "2"); + properties.put("kaptcha.textproducer.char.length", "4"); + properties.put("kaptcha.noise.color", "gray"); + properties.put("kaptcha.textproducer.char.string", "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); + Config config = new Config(properties); + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + defaultKaptcha.setConfig(config); + return defaultKaptcha; + } +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/common/R.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/common/R.java new file mode 100644 index 0000000..d466799 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/common/R.java @@ -0,0 +1,56 @@ +package com.timebusker.common; + +import org.apache.http.HttpStatus; + +import java.util.HashMap; +import java.util.Map; + +/** + * 返回数据结果集 + * + * @date 2016年10月27日 下午9:59:27 + */ +public class R extends HashMap { + + private static final long serialVersionUID = 1L; + + public R() { + put("code", 0); + } + + public static R error() { + return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员"); + } + + public static R error(String msg) { + return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg); + } + + public static R error(int code, String msg) { + R r = new R(); + r.put("code", code); + r.put("msg", msg); + return r; + } + + public static R ok(String msg) { + R r = new R(); + r.put("msg", msg); + return r; + } + + public static R ok(Map map) { + R r = new R(); + r.putAll(map); + return r; + } + + public static R ok() { + return new R(); + } + + public R put(String key, Object value) { + super.put(key, value); + return this; + } +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/entity/OssEntity.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/entity/OssEntity.java new file mode 100644 index 0000000..c26507c --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/entity/OssEntity.java @@ -0,0 +1,59 @@ +package com.timebusker.entity; + +import java.util.Date; + +/** + * @DESC:OssEntity:OSS对象存储文件实体 + * @author:timebusker + * @date:2018/8/30 + */ +public class OssEntity { + + private String id; + //URL地址 + private String url; + //创建时间 + private Date createDate; + + /** + * 设置: + */ + public void setId(String id) { + this.id = id; + } + + /** + * 获取: + */ + public String getId() { + return id; + } + + /** + * 设置:URL地址 + */ + public void setUrl(String url) { + this.url = url; + } + + /** + * 获取:URL地址 + */ + public String getUrl() { + return url; + } + + /** + * 设置:创建时间 + */ + public void setCreateDate(Date createDate) { + this.createDate = createDate; + } + + /** + * 获取:创建时间 + */ + public Date getCreateDate() { + return createDate; + } +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/entity/UserEntity.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/entity/UserEntity.java new file mode 100644 index 0000000..5fb0bf5 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/entity/UserEntity.java @@ -0,0 +1,105 @@ +package com.timebusker.entity; + +/** + * @DESC:UserEntity + * @author:timebusker + * @date:2018/8/29 + */ +public class UserEntity { + + /** + * 用户ID + */ + private Long userId; + + /** + * 用户名 + */ + private String username; + + /** + * 密码 + */ + private String password; + + /** + * 盐 + */ + private String salt; + + /** + * 邮箱 + */ + private String email; + + /** + * 手机号 + */ + private String mobile; + + /** + * 状态 0:禁用 1:正常 + */ + private Integer status; + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getSalt() { + return salt; + } + + public void setSalt(String salt) { + this.salt = salt; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getMobile() { + return mobile; + } + + public void setMobile(String mobile) { + this.mobile = mobile; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + @Override + public String toString() { + return super.toString(); + } +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/exception/CommonException.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/exception/CommonException.java new file mode 100644 index 0000000..f194e67 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/exception/CommonException.java @@ -0,0 +1,70 @@ +package com.timebusker.exception; + +public class CommonException extends RuntimeException { + + private static final long serialVersionUID = -1104674993657790702L; + + /** + * 生成序列异常时 + */ + public static final CommonException DB_GET_SEQ_NEXT_VALUE_ERROR = new CommonException(10040007, "序列生成超时"); + + /** + * 具体异常码 + */ + protected int code; + + /** + * 异常信息 + */ + protected String msg; + + /** + * + * @param message + */ + public CommonException(String message) { + super(message); + } + + public CommonException(int code, String msgFormat, Object... args) { + super(String.format(msgFormat, args)); + this.code = code; + this.msg = String.format(msgFormat, args); + } + + public CommonException(String message, Throwable cause) { + super(message, cause); + } + + public CommonException(Throwable cause) { + super(cause); + } + + /** + * 实例化异常 + * + * @param msgFormat + * @param args + * @return + */ + public CommonException newInstance(String msgFormat, Object... args) { + return new CommonException(this.code, msgFormat, args); + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/exception/CommonExceptionHandler.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/exception/CommonExceptionHandler.java new file mode 100644 index 0000000..bfc115d --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/exception/CommonExceptionHandler.java @@ -0,0 +1,55 @@ +package com.timebusker.exception; + +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; + +/** + * 创建全局异常处理类:通过使用@ControllerAdvice定义统一的异常处理类, + * 而不是在每个Controller中逐个定义。 + * + * @DESC:CommonExceptionHandler + * @author:timebusker + * @date:2018/8/22 + */ +@ControllerAdvice +public class CommonExceptionHandler { + /** + * 在@ControllerAdvice标记类中,根据抛出的具体Exception类型匹配 + * @ExceptionHandler中配置的异常类型来匹配错误映射和处理 + */ + + /** + * 统一错误页面 + */ + public static final String DEFAULT_ERROR_VIEW = "error"; + + /** + * 捕获自定义异常,返回json信息 + * @ExceptionHandler用来定义函数针对的异常类型,最后将Exception对象和请求URL映射到error.html中 + */ + @ExceptionHandler(value = CommonException.class) + public ModelAndView ErrorHandler(HttpServletRequest req, CommonException e) throws Exception { + ModelAndView mv = new ModelAndView(); + ErrorMassage error = new ErrorMassage<>(); + error.setCode(404); + error.setMessage("Not Found Exception......"); + error.setUrl(req.getRequestURL().toString()); + error.setData(e); + mv.addObject(error); + mv.setViewName(DEFAULT_ERROR_VIEW); + return mv; + } + + @ExceptionHandler(value = Exception.class) + @ResponseBody + public ErrorMassage ErrorHandler(HttpServletRequest req, Exception e) throws Exception { + ErrorMassage error = new ErrorMassage(); + error.setCode(400); + error.setMessage("系统异常"); + error.setUrl(req.getRequestURI()); + error.setData(e); + return error; + } +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/exception/ErrorMassage.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/exception/ErrorMassage.java new file mode 100644 index 0000000..3b026ce --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/exception/ErrorMassage.java @@ -0,0 +1,44 @@ +package com.timebusker.exception; + +public class ErrorMassage { + + public static final Integer OK = 0; + public static final Integer ERROR = 100; + + private Integer code; + private String message; + private String url; + private T data; + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/oauth2/OAuth2Filter.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/oauth2/OAuth2Filter.java new file mode 100644 index 0000000..0c257bf --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/oauth2/OAuth2Filter.java @@ -0,0 +1,79 @@ +package com.timebusker.oauth2; + +import com.alibaba.fastjson.JSON; +import com.timebusker.common.R; +import org.apache.commons.lang.StringUtils; +import org.apache.http.HttpStatus; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.AuthenticationToken; +import org.apache.shiro.web.filter.authc.AuthenticatingFilter; + +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * oauth2过滤器 + * + */ +public class OAuth2Filter extends AuthenticatingFilter { + + @Override + protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception { + //获取请求token + String token = getRequestToken((HttpServletRequest) request); + if(StringUtils.isBlank(token)){ + return null; + } + return new OAuth2Token(token); + } + + @Override + protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { + return false; + } + + @Override + protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { + //获取请求token,如果token不存在,直接返回401 + String token = getRequestToken((HttpServletRequest) request); + if(StringUtils.isBlank(token)){ + HttpServletResponse httpResponse = (HttpServletResponse) response; + String json = JSON.toJSONString(R.error(HttpStatus.SC_UNAUTHORIZED, "invalid token")); + httpResponse.getWriter().print(json); + return false; + } + return executeLogin(request, response); + } + + @Override + protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) { + HttpServletResponse httpResponse = (HttpServletResponse) response; + httpResponse.setContentType("application/json;charset=utf-8"); + try { + //处理登录失败的异常 + Throwable throwable = e.getCause() == null ? e : e.getCause(); + R r = R.error(HttpStatus.SC_UNAUTHORIZED, throwable.getMessage()); + String json = JSON.toJSONString(r); + httpResponse.getWriter().print(json); + } catch (IOException e1) { + e1.printStackTrace(); + } + return false; + } + + /** + * 获取请求的token + */ + private String getRequestToken(HttpServletRequest httpRequest){ + //从header中获取token + String token = httpRequest.getHeader("token"); + //如果header中不存在token,则从参数中获取token + if(StringUtils.isBlank(token)){ + token = httpRequest.getParameter("token"); + } + return token; + } +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/oauth2/OAuth2Realm.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/oauth2/OAuth2Realm.java new file mode 100644 index 0000000..5a0d245 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/oauth2/OAuth2Realm.java @@ -0,0 +1,49 @@ +package com.timebusker.oauth2; + +import org.apache.shiro.authc.*; +import org.apache.shiro.authz.AuthorizationInfo; +import org.apache.shiro.realm.AuthorizingRealm; +import org.apache.shiro.subject.PrincipalCollection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * 认证 + * + * @author chenshun + * @email sunlightcs@gmail.com + * @date 2017-05-20 14:00 + */ +@Component +public class OAuth2Realm extends AuthorizingRealm { + + private static final Logger LOGGER = LoggerFactory.getLogger(OAuth2Realm.class); + + @Override + public boolean supports(AuthenticationToken token) { + return token instanceof OAuth2Token; + } + + /** + * 授权(验证权限时调用) + */ + @Override + protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { + LOGGER.info("******************************\t\t 开始授权 \t\t******************************"); + + LOGGER.info("******************************\t\t 授权结束 \t\t******************************"); + return null; + } + + /** + * 认证(登录时调用) + */ + @Override + protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { + LOGGER.info("******************************\t\t 开始认证 \t\t******************************"); + + LOGGER.info("******************************\t\t 认证结束 \t\t******************************"); + return null; + } +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/oauth2/OAuth2Token.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/oauth2/OAuth2Token.java new file mode 100644 index 0000000..60c7726 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/oauth2/OAuth2Token.java @@ -0,0 +1,30 @@ +package com.timebusker.oauth2; + + +import org.apache.shiro.authc.AuthenticationToken; + +/** + * token + * + * @author chenshun + * @email sunlightcs@gmail.com + * @date 2017-05-20 13:22 + */ +public class OAuth2Token implements AuthenticationToken { + + private String token; + + public OAuth2Token(String token) { + this.token = token; + } + + @Override + public String getPrincipal() { + return token; + } + + @Override + public Object getCredentials() { + return token; + } +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/oauth2/TokenGenerator.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/oauth2/TokenGenerator.java new file mode 100644 index 0000000..94b8964 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/oauth2/TokenGenerator.java @@ -0,0 +1,46 @@ +package com.timebusker.oauth2; + +import com.timebusker.exception.CommonException; + +import java.security.MessageDigest; +import java.util.UUID; + +/** + * 生成token + * + * @author chenshun + * @email sunlightcs@gmail.com + * @date 2017-05-20 14:41 + */ +public class TokenGenerator { + + public static String generateValue() { + return generateValue(UUID.randomUUID().toString()); + } + + private static final char[] hexCode = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray(); + + public static String toHexString(byte[] data) { + if (data == null) { + return null; + } + StringBuilder r = new StringBuilder(data.length * 2); + for (byte b : data) { + r.append(hexCode[(b >> 4) & 0xF]); + r.append(hexCode[(b & 0xF)]); + } + return r.toString(); + } + + public static String generateValue(String param) { + try { + MessageDigest algorithm = MessageDigest.getInstance("MD5"); + algorithm.reset(); + algorithm.update(param.getBytes()); + byte[] messageDigest = algorithm.digest(); + return toHexString(messageDigest); + } catch (Exception e) { + throw new CommonException("生成Token失败", e); + } + } +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/service/UserTokenService.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/service/UserTokenService.java new file mode 100644 index 0000000..1119984 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/service/UserTokenService.java @@ -0,0 +1,19 @@ +package com.timebusker.service; + +import com.timebusker.common.R; + +/** + * @DESC:UserTokenService + * @author:timebusker + * @date:2018/8/29 + */ +public interface UserTokenService { + + /** + * 登录token生成 + * + * @param userId + * @return + */ + public R createToken(String userId); +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/service/impl/UserTokenServiceImpl.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/service/impl/UserTokenServiceImpl.java new file mode 100644 index 0000000..2692e12 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/service/impl/UserTokenServiceImpl.java @@ -0,0 +1,29 @@ +package com.timebusker.service.impl; + +import com.timebusker.common.R; +import com.timebusker.oauth2.TokenGenerator; +import com.timebusker.service.UserTokenService; + +import java.util.Date; + +/** + * @DESC:UserTokenServiceImpl + * @author:timebusker + * @date:2018/8/29 + */ +public class UserTokenServiceImpl implements UserTokenService { + + // 2小时后过期 + private final static int EXPIRE = 1000 * 60 * 60 * 2; + + @Override + public R createToken(String userId) { + // 生成一个token + // String token = TokenGenerator.generateValue(); + String token = userId; + //过期时间 + Date expireTime = new Date(new Date().getTime() + EXPIRE); + R r = R.ok().put("token", token).put("expire", expireTime); + return r; + } +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/utils/LoginFilter.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/utils/LoginFilter.java new file mode 100644 index 0000000..2b4d115 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/utils/LoginFilter.java @@ -0,0 +1,44 @@ +package com.timebusker.utils; + +import org.apache.commons.lang.StringUtils; + +import javax.servlet.*; +import javax.servlet.http.*; +import java.io.IOException; + +/** + * @DESC:LoginFilter + * @author:timebusker + * @date:2018/8/23 + */ +public class LoginFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + HttpServletRequest httpRequest = (HttpServletRequest) servletRequest; + HttpServletResponse httpResponse = (HttpServletResponse) servletResponse; + HttpSession session = httpRequest.getSession(); + String url = httpRequest.getRequestURI(); + String USER_ACCOUNT = (String) session.getAttribute("USER_ACCOUNT"); +// if (url.indexOf("login") > 0 || url.indexOf("authcode") >= 0) { +// filterChain.doFilter(servletRequest, servletResponse); +// } +// if (StringUtils.isNotBlank(USER_ACCOUNT)) { +// filterChain.doFilter(servletRequest, servletResponse); +// } else { +// httpResponse.sendRedirect("/sys/tologin"); +// } + filterChain.doFilter(servletRequest, servletResponse); + + } + + @Override + public void destroy() { + + } +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/utils/PageUtils.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/utils/PageUtils.java new file mode 100644 index 0000000..ea7232c --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/utils/PageUtils.java @@ -0,0 +1,81 @@ +package com.timebusker.utils; + +import java.io.Serializable; +import java.util.List; + +/** + * 分页工具类 + * + + * @date 2016年11月4日 下午12:59:00 + */ +public class PageUtils implements Serializable { + + private static final long serialVersionUID = 1L; + //总记录数 + private int totalCount; + //每页记录数 + private int pageSize; + //总页数 + private int totalPage; + //当前页数 + private int currPage; + //列表数据 + private List list; + + /** + * 分页 + * @param list 列表数据 + * @param totalCount 总记录数 + * @param pageSize 每页记录数 + * @param currPage 当前页数 + */ + public PageUtils(List list, int totalCount, int pageSize, int currPage) { + this.list = list; + this.totalCount = totalCount; + this.pageSize = pageSize; + this.currPage = currPage; + this.totalPage = (int)Math.ceil((double)totalCount/pageSize); + } + + public int getTotalCount() { + return totalCount; + } + + public void setTotalCount(int totalCount) { + this.totalCount = totalCount; + } + + public int getPageSize() { + return pageSize; + } + + public void setPageSize(int pageSize) { + this.pageSize = pageSize; + } + + public int getTotalPage() { + return totalPage; + } + + public void setTotalPage(int totalPage) { + this.totalPage = totalPage; + } + + public int getCurrPage() { + return currPage; + } + + public void setCurrPage(int currPage) { + this.currPage = currPage; + } + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/utils/Query.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/utils/Query.java new file mode 100644 index 0000000..d9c834f --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/utils/Query.java @@ -0,0 +1,57 @@ +package com.timebusker.utils; + +import org.apache.commons.lang.StringUtils; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * 查询参数 + * + + * @date 2017-03-14 23:15 + */ +public class Query extends LinkedHashMap { + + private static final long serialVersionUID = 1L; + //当前页码 + private int page; + //每页条数 + private int limit; + + public Query(Map params){ + this.putAll(params); + //分页参数 + this.page = Integer.parseInt(params.get("page").toString()); + this.limit = Integer.parseInt(params.get("limit").toString()); + this.put("offset", (page - 1) * limit); + this.put("page", page); + this.put("limit", limit); + //防止SQL注入(因为sidx、order是通过拼接SQL实现排序的,会有SQL注入风险) + String sidx = (String)params.get("sidx"); + String order = (String)params.get("order"); + if(StringUtils.isNotBlank(sidx)){ + this.put("sidx", SQLFilter.sqlInject(sidx)); + } + if(StringUtils.isNotBlank(order)){ + this.put("order", SQLFilter.sqlInject(order)); + } + + } + + public int getPage() { + return page; + } + + public void setPage(int page) { + this.page = page; + } + + public int getLimit() { + return limit; + } + + public void setLimit(int limit) { + this.limit = limit; + } +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/utils/SQLFilter.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/utils/SQLFilter.java new file mode 100644 index 0000000..e703d60 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/utils/SQLFilter.java @@ -0,0 +1,39 @@ +package com.timebusker.utils; + +import com.timebusker.exception.CommonException; +import org.apache.commons.lang.StringUtils; + +/** + * SQL过滤 + * @author chenshun + * @email sunlightcs@gmail.com + * @date 2017-04-01 16:16 + */ +public class SQLFilter { + + /** + * SQL注入过滤 + * @param str 待验证的字符串 + */ + public static String sqlInject(String str){ + if(StringUtils.isBlank(str)){ + return null; + } + //去掉'|"|;|\字符 + str = StringUtils.replace(str, "'", ""); + str = StringUtils.replace(str, "\"", ""); + str = StringUtils.replace(str, ";", ""); + str = StringUtils.replace(str, "\\", ""); + //转换成小写 + str = str.toLowerCase(); + //非法字符 + String[] keywords = {"master", "truncate", "insert", "select", "delete", "update", "declare", "alert", "drop"}; + //判断是否包含非法字符 + for(String keyword : keywords){ + if(str.indexOf(keyword) != -1){ + throw new CommonException("包含非法字符"); + } + } + return str; + } +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/web/AbstractController.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/web/AbstractController.java new file mode 100644 index 0000000..996d732 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/web/AbstractController.java @@ -0,0 +1,92 @@ +package com.timebusker.web; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.http.HttpRequest; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; + +import javax.servlet.http.*; + +/** + * @DESC:AbstractController:抽象类 + * @author:timebusker + * @date:2018/8/22 + */ +public abstract class AbstractController implements ApplicationContextAware { + + protected Logger logger = LoggerFactory.getLogger(getClass()); + + public static ApplicationContext applicationContext; + protected HttpServletRequest request; + protected HttpServletResponse response; + protected HttpSession session; + + /** + * 在方法定义上使用@ModelAttribute + * 在SpringMVC调用任何方法前,被@ModelAttribute注解的方法都会先被依次调用, + * 并且这些注解方法的返回值都会被添加到模型中。 + * + * @param request + * @param response + * @param session + */ + @ModelAttribute + public void before(HttpServletRequest request, HttpServletResponse response, HttpSession session) { + this.request = request; + this.response = response; + this.session = session; + if ((request.getRequestURI().indexOf("login") < 0 || request.getRequestURI().indexOf("authcode") < 0) && null == session.getAttribute("USER_ACCOUNT")) { + try { + this.login(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * 指定到登录页面 + * + * @return + */ + @RequestMapping(value = {"/"}) + public String login() { + return "login"; + } + + /** + * 手动 IoC 上下文信息 + * + * @param applicationContext + * @throws BeansException + */ + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + AbstractController.applicationContext = applicationContext; + } + + public static Object getBean(String name) { + return applicationContext.getBean(name); + } + + public static T getBean(String name, Class requiredType) { + return applicationContext.getBean(name, requiredType); + } + + public static boolean containsBean(String name) { + return applicationContext.containsBean(name); + } + + public static boolean isSingleton(String name) { + return applicationContext.isSingleton(name); + } + + public static Class getType(String name) { + return applicationContext.getType(name); + } + +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/web/HdfsApiController.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/web/HdfsApiController.java new file mode 100644 index 0000000..f19c64f --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/web/HdfsApiController.java @@ -0,0 +1,38 @@ +package com.timebusker.web; + +import com.timebusker.common.R; +import com.timebusker.entity.OssEntity; +import com.timebusker.utils.PageUtils; +import com.timebusker.utils.Query; +import org.springframework.web.bind.annotation.*; + +import java.util.*; + +/** + * @DESC:HdfsApiController + * @author:timebusker + * @date:2018/8/30 + */ +@RestController +@RequestMapping("/hdfs") +public class HdfsApiController extends AbstractController { + + /** + * 列表 + */ + @RequestMapping("/list") + public R list(@RequestParam Map params) { + //查询列表数据 + Query query = new Query(params); + List ossList = new ArrayList(); + for (int i = 0; i < 10; i++) { + OssEntity oss = new OssEntity(); + oss.setId(i + "_" + System.currentTimeMillis()); + oss.setUrl("http://www.timebusker.top/master/img/top-photo/" + i + ".jpg"); + oss.setCreateDate(new Date()); + } + int total = 1; + PageUtils pageUtil = new PageUtils(ossList, total, query.getLimit(), query.getPage()); + return R.ok().put("page", pageUtil); + } +} diff --git a/spring-boot-22-FarstPlus/src/main/java/com/timebusker/web/IndexController.java b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/web/IndexController.java new file mode 100644 index 0000000..ec3761a --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/java/com/timebusker/web/IndexController.java @@ -0,0 +1,72 @@ +package com.timebusker.web; + +import com.google.code.kaptcha.Constants; +import com.google.code.kaptcha.Producer; +import com.timebusker.exception.CommonException; +import com.timebusker.common.R; +import org.apache.commons.io.IOUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.Map; + +/** + * @DESC:IndexController + * @author:timebusker + * @date:2018/8/22 + */ +@Controller +public class IndexController extends AbstractController { + + @Autowired + private Producer producer; + + private static final String USER_ACCOUNT = "admin"; + + /** + * 获取验证码 + * + * @throws CommonException + * @throws IOException + */ + @RequestMapping("/authcode") + public void captcha() throws CommonException, IOException { + response.setHeader("Cache-Control", "no-store, no-cache"); + response.setContentType("image/jpeg"); + //生成文字验证码 + String text = producer.createText(); + //生成图片验证码 + BufferedImage image = producer.createImage(text); + //保存到shiro session + session.setAttribute(Constants.KAPTCHA_SESSION_KEY, text); + // 输出验证码图片到页面 + ServletOutputStream out = response.getOutputStream(); + ImageIO.write(image, "jpg", out); + IOUtils.closeQuietly(out); + } + + /** + * 登录 + */ + @RequestMapping(value = "/login", method = RequestMethod.POST) + @ResponseBody + public Map login(String username, String password, String captcha) throws IOException { + String kaptcha = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY); +// if(!captcha.equalsIgnoreCase(kaptcha)){ +// return R.error("验证码不正确"); +// } + if (!USER_ACCOUNT.equals(username)) { + return R.error("账户不正确"); + } + if (!USER_ACCOUNT.equals(password)) { + return R.error("密码不正确"); + } + session.setAttribute("USER_ACCOUNT", USER_ACCOUNT); + return R.ok().put("token", USER_ACCOUNT); + } +} diff --git a/spring-boot-22-FarstPlus/src/main/resources/application.properties b/spring-boot-22-FarstPlus/src/main/resources/application.properties new file mode 100644 index 0000000..c5c3d62 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/application.properties @@ -0,0 +1,21 @@ +#\u670D\u52A1\u7AEF\u53E3 +server.port=80 +server.context-path=/fastplus +server.error.path=/error +server.jetty.acceptors=10 + +#freemarker\u914D\u7F6E +# jackson\u65F6\u95F4\u683C\u5F0F\u5316 +spring.jackson.time-zone=GMT+8 +spring.jackson.date-format=yyyy-MM-dd HH:mm:ss +spring.http.multipart.max-file-size=100MB +spring.http.multipart.max-request-size=100MB +spring.http.multipart.enabled=true +spring.resources.static-locations=classpath:/templates/static/,classpath:/templates/views/ + +spring.freemarker.cache=false +spring.freemarker.checkTemplateLocation=true +spring.freemarker.contentType=text/html +spring.freemarker.suffix=.html +spring.freemarker.templateEncoding=UTF-8 +spring.freemarker.templateLoaderPath=classpath:/templates/views/ \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/resources/logback-spring.xml b/spring-boot-22-FarstPlus/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..b1496a9 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/logback-spring.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/apple-icon-144x144.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/apple-icon-144x144.png new file mode 100644 index 0000000..c30cbd9 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/apple-icon-144x144.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/css/AdminLTE.min.css b/spring-boot-22-FarstPlus/src/main/resources/templates/static/css/AdminLTE.min.css new file mode 100644 index 0000000..25de721 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/css/AdminLTE.min.css @@ -0,0 +1,5211 @@ +/*! + * AdminLTE v2.3.8 + * Author: Almsaeed Studio + * Website: Almsaeed Studio + * License: Open source - MIT + * Please visit http://opensource.org/licenses/MIT for more information +!*/ +html, body { + height: 100% +} + +.layout-boxed html, .layout-boxed body { + height: 100% +} + +body { + font-family: 'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-weight: 400; + overflow-x: hidden; + overflow-y: auto +} + +.wrapper { + height: 100%; + position: relative; + overflow-x: hidden; + overflow-y: auto +} + +.wrapper:before, .wrapper:after { + content: " "; + display: table +} + +.wrapper:after { + clear: both +} + +.layout-boxed .wrapper { + max-width: 1250px; + margin: 0 auto; + min-height: 100%; + box-shadow: 0 0 8px rgba(0, 0, 0, 0.5); + position: relative +} + +.layout-boxed { + background: url('../img/boxed-bg.jpg') repeat fixed +} + +.content-wrapper, .right-side, .main-footer { + -webkit-transition: -webkit-transform .3s ease-in-out, margin .3s ease-in-out; + -moz-transition: -moz-transform .3s ease-in-out, margin .3s ease-in-out; + -o-transition: -o-transform .3s ease-in-out, margin .3s ease-in-out; + transition: transform .3s ease-in-out, margin .3s ease-in-out; + margin-left: 230px; + z-index: 820 +} + +.layout-top-nav .content-wrapper, .layout-top-nav .right-side, .layout-top-nav .main-footer { + margin-left: 0 +} + +@media (max-width: 767px) { + .content-wrapper, .right-side, .main-footer { + margin-left: 0 + } +} + +@media (min-width: 768px) { + .sidebar-collapse .content-wrapper, .sidebar-collapse .right-side, .sidebar-collapse .main-footer { + margin-left: 0 + } +} + +@media (max-width: 767px) { + .sidebar-open .content-wrapper, .sidebar-open .right-side, .sidebar-open .main-footer { + -webkit-transform: translate(230px, 0); + -ms-transform: translate(230px, 0); + -o-transform: translate(230px, 0); + transform: translate(230px, 0) + } +} + +.content-wrapper, .right-side { + min-height: 100%; + background-color: #ecf0f5; + z-index: 800 +} + +.main-footer { + background: #fff; + padding: 15px; + color: #444; + border-top: 1px solid #d2d6de +} + +.fixed .main-header, .fixed .main-sidebar, .fixed .left-side { + position: fixed +} + +.fixed .main-header { + top: 0; + right: 0; + left: 0 +} + +.fixed .content-wrapper, .fixed .right-side { + padding-top: 50px +} + +@media (max-width: 767px) { + .fixed .content-wrapper, .fixed .right-side { + padding-top: 100px + } +} + +.fixed.layout-boxed .wrapper { + max-width: 100% +} + +body.hold-transition .content-wrapper, body.hold-transition .right-side, body.hold-transition .main-footer, body.hold-transition .main-sidebar, body.hold-transition .left-side, body.hold-transition .main-header .navbar, body.hold-transition .main-header .logo { + -webkit-transition: none; + -o-transition: none; + transition: none +} + +.content { + min-height: 250px; + padding: 15px; + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px +} + +h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { + font-family: 'Source Sans Pro', sans-serif +} + +a { + color: #3c8dbc +} + +a:hover, a:active, a:focus { + outline: none; + text-decoration: none; + color: #72afd2 +} + +.page-header { + margin: 10px 0 20px 0; + font-size: 22px +} + +.page-header > small { + color: #666; + display: block; + margin-top: 5px +} + +.main-header { + position: relative; + max-height: 100px; + z-index: 1030 +} + +.main-header .navbar { + -webkit-transition: margin-left .3s ease-in-out; + -o-transition: margin-left .3s ease-in-out; + transition: margin-left .3s ease-in-out; + margin-bottom: 0; + margin-left: 230px; + border: none; + min-height: 50px; + border-radius: 0 +} + +.layout-top-nav .main-header .navbar { + margin-left: 0 +} + +.main-header #navbar-search-input.form-control { + background: rgba(255, 255, 255, 0.2); + border-color: transparent +} + +.main-header #navbar-search-input.form-control:focus, .main-header #navbar-search-input.form-control:active { + border-color: rgba(0, 0, 0, 0.1); + background: rgba(255, 255, 255, 0.9) +} + +.main-header #navbar-search-input.form-control::-moz-placeholder { + color: #ccc; + opacity: 1 +} + +.main-header #navbar-search-input.form-control:-ms-input-placeholder { + color: #ccc +} + +.main-header #navbar-search-input.form-control::-webkit-input-placeholder { + color: #ccc +} + +.main-header .navbar-custom-menu, .main-header .navbar-right { + float: right +} + +@media (max-width: 991px) { + .main-header .navbar-custom-menu a, .main-header .navbar-right a { + color: inherit; + background: transparent + } +} + +@media (max-width: 767px) { + .main-header .navbar-right { + float: none + } + + .navbar-collapse .main-header .navbar-right { + margin: 7.5px -15px + } + + .main-header .navbar-right > li { + color: inherit; + border: 0 + } +} + +.main-header .sidebar-toggle { + float: left; + background-color: transparent; + background-image: none; + padding: 15px 15px; + font-family: fontAwesome +} + +.main-header .sidebar-toggle:before { + content: "\f0c9" +} + +.main-header .sidebar-toggle:hover { + color: #fff +} + +.main-header .sidebar-toggle:focus, .main-header .sidebar-toggle:active { + background: transparent +} + +.main-header .sidebar-toggle .icon-bar { + display: none +} + +.main-header .navbar .nav > li.user > a > .fa, .main-header .navbar .nav > li.user > a > .glyphicon, .main-header .navbar .nav > li.user > a > .ion { + margin-right: 5px +} + +.main-header .navbar .nav > li > a > .label { + position: absolute; + top: 9px; + right: 7px; + text-align: center; + font-size: 9px; + padding: 2px 3px; + line-height: .9 +} + +.main-header .logo { + -webkit-transition: width .3s ease-in-out; + -o-transition: width .3s ease-in-out; + transition: width .3s ease-in-out; + display: block; + float: left; + height: 50px; + font-size: 20px; + line-height: 50px; + text-align: center; + width: 230px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + padding: 0 15px; + font-weight: 300; + overflow: hidden +} + +.main-header .logo .logo-lg { + display: block +} + +.main-header .logo .logo-mini { + display: none +} + +.main-header .navbar-brand { + color: #fff +} + +.content-header { + position: relative; + padding: 15px 15px 0 15px +} + +.content-header > h1 { + margin: 0; + font-size: 24px +} + +.content-header > h1 > small { + font-size: 15px; + display: inline-block; + padding-left: 4px; + font-weight: 300 +} + +.content-header > .breadcrumb { + float: right; + background: transparent; + margin-top: 0; + margin-bottom: 0; + font-size: 12px; + padding: 7px 5px; + position: absolute; + top: 15px; + right: 10px; + border-radius: 2px +} + +.content-header > .breadcrumb > li > a { + color: #444; + text-decoration: none; + display: inline-block +} + +.content-header > .breadcrumb > li > a > .fa, .content-header > .breadcrumb > li > a > .glyphicon, .content-header > .breadcrumb > li > a > .ion { + margin-right: 5px +} + +.content-header > .breadcrumb > li + li:before { + content: '>\00a0' +} + +@media (max-width: 991px) { + .content-header > .breadcrumb { + position: relative; + margin-top: 5px; + top: 0; + right: 0; + float: none; + background: #d2d6de; + padding-left: 10px + } + + .content-header > .breadcrumb li:before { + color: #97a0b3 + } +} + +.navbar-toggle { + color: #fff; + border: 0; + margin: 0; + padding: 15px 15px +} + +@media (max-width: 991px) { + .navbar-custom-menu .navbar-nav > li { + float: left + } + + .navbar-custom-menu .navbar-nav { + margin: 0; + float: left + } + + .navbar-custom-menu .navbar-nav > li > a { + padding-top: 15px; + padding-bottom: 15px; + line-height: 20px + } +} + +@media (max-width: 767px) { + .main-header { + position: relative + } + + .main-header .logo, .main-header .navbar { + width: 100%; + float: none + } + + .main-header .navbar { + margin: 0 + } + + .main-header .navbar-custom-menu { + float: right + } +} + +@media (max-width: 991px) { + .navbar-collapse.pull-left { + float: none !important + } + + .navbar-collapse.pull-left + .navbar-custom-menu { + display: block; + position: absolute; + top: 0; + right: 40px + } +} + +.main-sidebar, .left-side { + position: absolute; + top: 0; + left: 0; + padding-top: 50px; + min-height: 100%; + width: 230px; + z-index: 810; + -webkit-transition: -webkit-transform .3s ease-in-out, width .3s ease-in-out; + -moz-transition: -moz-transform .3s ease-in-out, width .3s ease-in-out; + -o-transition: -o-transform .3s ease-in-out, width .3s ease-in-out; + transition: transform .3s ease-in-out, width .3s ease-in-out +} + +@media (max-width: 767px) { + .main-sidebar, .left-side { + padding-top: 100px + } +} + +@media (max-width: 767px) { + .main-sidebar, .left-side { + -webkit-transform: translate(-230px, 0); + -ms-transform: translate(-230px, 0); + -o-transform: translate(-230px, 0); + transform: translate(-230px, 0) + } +} + +@media (min-width: 768px) { + .sidebar-collapse .main-sidebar, .sidebar-collapse .left-side { + -webkit-transform: translate(-230px, 0); + -ms-transform: translate(-230px, 0); + -o-transform: translate(-230px, 0); + transform: translate(-230px, 0) + } +} + +@media (max-width: 767px) { + .sidebar-open .main-sidebar, .sidebar-open .left-side { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0) + } +} + +.sidebar { + padding-bottom: 10px +} + +.sidebar-form input:focus { + border-color: transparent +} + +.user-panel { + position: relative; + width: 100%; + padding: 10px; + overflow: hidden +} + +.user-panel:before, .user-panel:after { + content: " "; + display: table +} + +.user-panel:after { + clear: both +} + +.user-panel > .image > img { + width: 100%; + max-width: 45px; + height: auto +} + +.user-panel > .info { + padding: 5px 5px 5px 15px; + line-height: 1; + position: absolute; + left: 55px +} + +.user-panel > .info > p { + font-weight: 600; + margin-bottom: 9px +} + +.user-panel > .info > a { + text-decoration: none; + padding-right: 5px; + margin-top: 3px; + font-size: 11px +} + +.user-panel > .info > a > .fa, .user-panel > .info > a > .ion, .user-panel > .info > a > .glyphicon { + margin-right: 3px +} + +.sidebar-menu { + list-style: none; + margin: 0; + padding: 0 +} + +.sidebar-menu > li { + position: relative; + margin: 0; + padding: 0 +} + +.sidebar-menu > li > a { + padding: 12px 5px 12px 15px; + display: block +} + +.sidebar-menu > li > a > .fa, .sidebar-menu > li > a > .glyphicon, .sidebar-menu > li > a > .ion { + width: 20px +} + +.sidebar-menu > li .label, .sidebar-menu > li .badge { + margin-right: 5px +} + +.sidebar-menu > li .badge { + margin-top: 3px +} + +.sidebar-menu li.header { + padding: 10px 25px 10px 15px; + font-size: 12px +} + +.sidebar-menu li > a > .fa-angle-left, .sidebar-menu li > a > .pull-right-container > .fa-angle-left { + width: auto; + height: auto; + padding: 0; + margin-right: 10px +} + +.sidebar-menu li > a > .fa-angle-left { + position: absolute; + top: 50%; + right: 10px; + margin-top: -8px +} + +.sidebar-menu li.active > a > .fa-angle-left, .sidebar-menu li.active > a > .pull-right-container > .fa-angle-left { + -webkit-transform: rotate(-90deg); + -ms-transform: rotate(-90deg); + -o-transform: rotate(-90deg); + transform: rotate(-90deg) +} + +.sidebar-menu li.active > .treeview-menu { + display: block +} + +.sidebar-menu .treeview-menu { + display: none; + list-style: none; + padding: 0; + margin: 0; + padding-left: 5px +} + +.sidebar-menu .treeview-menu .treeview-menu { + padding-left: 20px +} + +.sidebar-menu .treeview-menu > li { + margin: 0 +} + +.sidebar-menu .treeview-menu > li > a { + padding: 5px 5px 5px 15px; + display: block; + font-size: 14px +} + +.sidebar-menu .treeview-menu > li > a > .fa, .sidebar-menu .treeview-menu > li > a > .glyphicon, .sidebar-menu .treeview-menu > li > a > .ion { + width: 20px +} + +.sidebar-menu .treeview-menu > li > a > .pull-right-container > .fa-angle-left, .sidebar-menu .treeview-menu > li > a > .pull-right-container > .fa-angle-down, .sidebar-menu .treeview-menu > li > a > .fa-angle-left, .sidebar-menu .treeview-menu > li > a > .fa-angle-down { + width: auto +} + +@media (min-width: 768px) { + .sidebar-mini.sidebar-collapse .content-wrapper, .sidebar-mini.sidebar-collapse .right-side, .sidebar-mini.sidebar-collapse .main-footer { + margin-left: 50px !important; + z-index: 840 + } + + .sidebar-mini.sidebar-collapse .main-sidebar { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0); + width: 50px !important; + z-index: 850 + } + + .sidebar-mini.sidebar-collapse .sidebar-menu > li { + position: relative + } + + .sidebar-mini.sidebar-collapse .sidebar-menu > li > a { + margin-right: 0 + } + + .sidebar-mini.sidebar-collapse .sidebar-menu > li > a > span { + border-top-right-radius: 4px + } + + .sidebar-mini.sidebar-collapse .sidebar-menu > li:not(.treeview) > a > span { + border-bottom-right-radius: 4px + } + + .sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu { + padding-top: 5px; + padding-bottom: 5px; + border-bottom-right-radius: 4px + } + + .sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right), .sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > .treeview-menu { + display: block !important; + position: absolute; + width: 180px; + left: 50px + } + + .sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span { + top: 0; + margin-left: -3px; + padding: 12px 5px 12px 20px; + background-color: inherit + } + + .sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > .pull-right-container { + position: relative !important; + float: right; + width: auto !important; + left: 180px !important; + top: -22px !important; + z-index: 900 + } + + .sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > .pull-right-container > .label:not(:first-of-type) { + display: none + } + + .sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > .treeview-menu { + top: 44px; + margin-left: 0 + } + + .sidebar-mini.sidebar-collapse .main-sidebar .user-panel > .info, .sidebar-mini.sidebar-collapse .sidebar-form, .sidebar-mini.sidebar-collapse .sidebar-menu > li > a > span, .sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu, .sidebar-mini.sidebar-collapse .sidebar-menu > li > a > .pull-right, .sidebar-mini.sidebar-collapse .sidebar-menu li.header { + display: none !important; + -webkit-transform: translateZ(0) + } + + .sidebar-mini.sidebar-collapse .main-header .logo { + width: 50px + } + + .sidebar-mini.sidebar-collapse .main-header .logo > .logo-mini { + display: block; + margin-left: -15px; + margin-right: -15px; + font-size: 18px + } + + .sidebar-mini.sidebar-collapse .main-header .logo > .logo-lg { + display: none + } + + .sidebar-mini.sidebar-collapse .main-header .navbar { + margin-left: 50px + } +} + +.sidebar-menu, .main-sidebar .user-panel, .sidebar-menu > li.header { + white-space: nowrap; + overflow: hidden +} + +.sidebar-menu:hover { + overflow: visible +} + +.sidebar-form, .sidebar-menu > li.header { + overflow: hidden; + text-overflow: clip +} + +.sidebar-menu li > a { + position: relative +} + +.sidebar-menu li > a > .pull-right-container { + position: absolute; + right: 10px; + top: 50%; + margin-top: -7px +} + +.control-sidebar-bg { + position: fixed; + z-index: 1000; + bottom: 0 +} + +.control-sidebar-bg, .control-sidebar { + top: 0; + right: -230px; + width: 230px; + -webkit-transition: right .3s ease-in-out; + -o-transition: right .3s ease-in-out; + transition: right .3s ease-in-out +} + +.control-sidebar { + position: absolute; + padding-top: 50px; + z-index: 1010 +} + +@media (max-width: 768px) { + .control-sidebar { + padding-top: 100px + } +} + +.control-sidebar > .tab-content { + padding: 10px 15px +} + +.control-sidebar.control-sidebar-open, .control-sidebar.control-sidebar-open + .control-sidebar-bg { + right: 0 +} + +.control-sidebar-open .control-sidebar-bg, .control-sidebar-open .control-sidebar { + right: 0 +} + +@media (min-width: 768px) { + .control-sidebar-open .content-wrapper, .control-sidebar-open .right-side, .control-sidebar-open .main-footer { + margin-right: 230px + } +} + +.nav-tabs.control-sidebar-tabs > li:first-of-type > a, .nav-tabs.control-sidebar-tabs > li:first-of-type > a:hover, .nav-tabs.control-sidebar-tabs > li:first-of-type > a:focus { + border-left-width: 0 +} + +.nav-tabs.control-sidebar-tabs > li > a { + border-radius: 0 +} + +.nav-tabs.control-sidebar-tabs > li > a, .nav-tabs.control-sidebar-tabs > li > a:hover { + border-top: none; + border-right: none; + border-left: 1px solid transparent; + border-bottom: 1px solid transparent +} + +.nav-tabs.control-sidebar-tabs > li > a .icon { + font-size: 16px +} + +.nav-tabs.control-sidebar-tabs > li.active > a, .nav-tabs.control-sidebar-tabs > li.active > a:hover, .nav-tabs.control-sidebar-tabs > li.active > a:focus, .nav-tabs.control-sidebar-tabs > li.active > a:active { + border-top: none; + border-right: none; + border-bottom: none +} + +@media (max-width: 768px) { + .nav-tabs.control-sidebar-tabs { + display: table + } + + .nav-tabs.control-sidebar-tabs > li { + display: table-cell + } +} + +.control-sidebar-heading { + font-weight: 400; + font-size: 16px; + padding: 10px 0; + margin-bottom: 10px +} + +.control-sidebar-subheading { + display: block; + font-weight: 400; + font-size: 14px +} + +.control-sidebar-menu { + list-style: none; + padding: 0; + margin: 0 -15px +} + +.control-sidebar-menu > li > a { + display: block; + padding: 10px 15px +} + +.control-sidebar-menu > li > a:before, .control-sidebar-menu > li > a:after { + content: " "; + display: table +} + +.control-sidebar-menu > li > a:after { + clear: both +} + +.control-sidebar-menu > li > a > .control-sidebar-subheading { + margin-top: 0 +} + +.control-sidebar-menu .menu-icon { + float: left; + width: 35px; + height: 35px; + border-radius: 50%; + text-align: center; + line-height: 35px +} + +.control-sidebar-menu .menu-info { + margin-left: 45px; + margin-top: 3px +} + +.control-sidebar-menu .menu-info > .control-sidebar-subheading { + margin: 0 +} + +.control-sidebar-menu .menu-info > p { + margin: 0; + font-size: 11px +} + +.control-sidebar-menu .progress { + margin: 0 +} + +.control-sidebar-dark { + color: #b8c7ce +} + +.control-sidebar-dark, .control-sidebar-dark + .control-sidebar-bg { + background: #222d32 +} + +.control-sidebar-dark .nav-tabs.control-sidebar-tabs { + border-bottom: #1c2529 +} + +.control-sidebar-dark .nav-tabs.control-sidebar-tabs > li > a { + background: #181f23; + color: #b8c7ce +} + +.control-sidebar-dark .nav-tabs.control-sidebar-tabs > li > a, .control-sidebar-dark .nav-tabs.control-sidebar-tabs > li > a:hover, .control-sidebar-dark .nav-tabs.control-sidebar-tabs > li > a:focus { + border-left-color: #141a1d; + border-bottom-color: #141a1d +} + +.control-sidebar-dark .nav-tabs.control-sidebar-tabs > li > a:hover, .control-sidebar-dark .nav-tabs.control-sidebar-tabs > li > a:focus, .control-sidebar-dark .nav-tabs.control-sidebar-tabs > li > a:active { + background: #1c2529 +} + +.control-sidebar-dark .nav-tabs.control-sidebar-tabs > li > a:hover { + color: #fff +} + +.control-sidebar-dark .nav-tabs.control-sidebar-tabs > li.active > a, .control-sidebar-dark .nav-tabs.control-sidebar-tabs > li.active > a:hover, .control-sidebar-dark .nav-tabs.control-sidebar-tabs > li.active > a:focus, .control-sidebar-dark .nav-tabs.control-sidebar-tabs > li.active > a:active { + background: #222d32; + color: #fff +} + +.control-sidebar-dark .control-sidebar-heading, .control-sidebar-dark .control-sidebar-subheading { + color: #fff +} + +.control-sidebar-dark .control-sidebar-menu > li > a:hover { + background: #1e282c +} + +.control-sidebar-dark .control-sidebar-menu > li > a .menu-info > p { + color: #b8c7ce +} + +.control-sidebar-light { + color: #5e5e5e +} + +.control-sidebar-light, .control-sidebar-light + .control-sidebar-bg { + background: #f9fafc; + border-left: 1px solid #d2d6de +} + +.control-sidebar-light .nav-tabs.control-sidebar-tabs { + border-bottom: #d2d6de +} + +.control-sidebar-light .nav-tabs.control-sidebar-tabs > li > a { + background: #e8ecf4; + color: #444 +} + +.control-sidebar-light .nav-tabs.control-sidebar-tabs > li > a, .control-sidebar-light .nav-tabs.control-sidebar-tabs > li > a:hover, .control-sidebar-light .nav-tabs.control-sidebar-tabs > li > a:focus { + border-left-color: #d2d6de; + border-bottom-color: #d2d6de +} + +.control-sidebar-light .nav-tabs.control-sidebar-tabs > li > a:hover, .control-sidebar-light .nav-tabs.control-sidebar-tabs > li > a:focus, .control-sidebar-light .nav-tabs.control-sidebar-tabs > li > a:active { + background: #eff1f7 +} + +.control-sidebar-light .nav-tabs.control-sidebar-tabs > li.active > a, .control-sidebar-light .nav-tabs.control-sidebar-tabs > li.active > a:hover, .control-sidebar-light .nav-tabs.control-sidebar-tabs > li.active > a:focus, .control-sidebar-light .nav-tabs.control-sidebar-tabs > li.active > a:active { + background: #f9fafc; + color: #111 +} + +.control-sidebar-light .control-sidebar-heading, .control-sidebar-light .control-sidebar-subheading { + color: #111 +} + +.control-sidebar-light .control-sidebar-menu { + margin-left: -14px +} + +.control-sidebar-light .control-sidebar-menu > li > a:hover { + background: #f4f4f5 +} + +.control-sidebar-light .control-sidebar-menu > li > a .menu-info > p { + color: #5e5e5e +} + +.dropdown-menu { + box-shadow: none; + border-color: #eee +} + +.dropdown-menu > li > a { + color: #777 +} + +.dropdown-menu > li > a > .glyphicon, .dropdown-menu > li > a > .fa, .dropdown-menu > li > a > .ion { + margin-right: 10px +} + +.dropdown-menu > li > a:hover { + background-color: #e1e3e9; + color: #333 +} + +.dropdown-menu > .divider { + background-color: #eee +} + +.navbar-nav > .notifications-menu > .dropdown-menu, .navbar-nav > .messages-menu > .dropdown-menu, .navbar-nav > .tasks-menu > .dropdown-menu { + width: 280px; + padding: 0 0 0 0; + margin: 0; + top: 100% +} + +.navbar-nav > .notifications-menu > .dropdown-menu > li, .navbar-nav > .messages-menu > .dropdown-menu > li, .navbar-nav > .tasks-menu > .dropdown-menu > li { + position: relative +} + +.navbar-nav > .notifications-menu > .dropdown-menu > li.header, .navbar-nav > .messages-menu > .dropdown-menu > li.header, .navbar-nav > .tasks-menu > .dropdown-menu > li.header { + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + background-color: #ffffff; + padding: 7px 10px; + border-bottom: 1px solid #f4f4f4; + color: #444444; + font-size: 14px +} + +.navbar-nav > .notifications-menu > .dropdown-menu > li.footer > a, .navbar-nav > .messages-menu > .dropdown-menu > li.footer > a, .navbar-nav > .tasks-menu > .dropdown-menu > li.footer > a { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; + font-size: 12px; + background-color: #fff; + padding: 7px 10px; + border-bottom: 1px solid #eeeeee; + color: #444 !important; + text-align: center +} + +@media (max-width: 991px) { + .navbar-nav > .notifications-menu > .dropdown-menu > li.footer > a, .navbar-nav > .messages-menu > .dropdown-menu > li.footer > a, .navbar-nav > .tasks-menu > .dropdown-menu > li.footer > a { + background: #fff !important; + color: #444 !important + } +} + +.navbar-nav > .notifications-menu > .dropdown-menu > li.footer > a:hover, .navbar-nav > .messages-menu > .dropdown-menu > li.footer > a:hover, .navbar-nav > .tasks-menu > .dropdown-menu > li.footer > a:hover { + text-decoration: none; + font-weight: normal +} + +.navbar-nav > .notifications-menu > .dropdown-menu > li .menu, .navbar-nav > .messages-menu > .dropdown-menu > li .menu, .navbar-nav > .tasks-menu > .dropdown-menu > li .menu { + max-height: 200px; + margin: 0; + padding: 0; + list-style: none; + overflow-x: hidden +} + +.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a, .navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a, .navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a { + display: block; + white-space: nowrap; + border-bottom: 1px solid #f4f4f4 +} + +.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a:hover, .navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:hover, .navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a:hover { + background: #f4f4f4; + text-decoration: none +} + +.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a { + color: #444444; + overflow: hidden; + text-overflow: ellipsis; + padding: 10px +} + +.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .glyphicon, .navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .fa, .navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .ion { + width: 20px +} + +.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a { + margin: 0; + padding: 10px 10px +} + +.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > div > img { + margin: auto 10px auto auto; + width: 40px; + height: 40px +} + +.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > h4 { + padding: 0; + margin: 0 0 0 45px; + color: #444444; + font-size: 15px; + position: relative +} + +.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > h4 > small { + color: #999999; + font-size: 10px; + position: absolute; + top: 0; + right: 0 +} + +.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > p { + margin: 0 0 0 45px; + font-size: 12px; + color: #888888 +} + +.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:before, .navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:after { + content: " "; + display: table +} + +.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:after { + clear: both +} + +.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a { + padding: 10px +} + +.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a > h3 { + font-size: 14px; + padding: 0; + margin: 0 0 10px 0; + color: #666666 +} + +.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a > .progress { + padding: 0; + margin: 0 +} + +.navbar-nav > .user-menu > .dropdown-menu { + border-top-right-radius: 0; + border-top-left-radius: 0; + padding: 1px 0 0 0; + border-top-width: 0; + width: 280px +} + +.navbar-nav > .user-menu > .dropdown-menu, .navbar-nav > .user-menu > .dropdown-menu > .user-body { + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px +} + +.navbar-nav > .user-menu > .dropdown-menu > li.user-header { + height: 175px; + padding: 10px; + text-align: center +} + +.navbar-nav > .user-menu > .dropdown-menu > li.user-header > img { + z-index: 5; + height: 90px; + width: 90px; + border: 3px solid; + border-color: transparent; + border-color: rgba(255, 255, 255, 0.2) +} + +.navbar-nav > .user-menu > .dropdown-menu > li.user-header > p { + z-index: 5; + color: #fff; + color: rgba(255, 255, 255, 0.8); + font-size: 17px; + margin-top: 10px +} + +.navbar-nav > .user-menu > .dropdown-menu > li.user-header > p > small { + display: block; + font-size: 12px +} + +.navbar-nav > .user-menu > .dropdown-menu > .user-body { + padding: 15px; + border-bottom: 1px solid #f4f4f4; + border-top: 1px solid #dddddd +} + +.navbar-nav > .user-menu > .dropdown-menu > .user-body:before, .navbar-nav > .user-menu > .dropdown-menu > .user-body:after { + content: " "; + display: table +} + +.navbar-nav > .user-menu > .dropdown-menu > .user-body:after { + clear: both +} + +.navbar-nav > .user-menu > .dropdown-menu > .user-body a { + color: #444 !important +} + +@media (max-width: 991px) { + .navbar-nav > .user-menu > .dropdown-menu > .user-body a { + background: #fff !important; + color: #444 !important + } +} + +.navbar-nav > .user-menu > .dropdown-menu > .user-footer { + background-color: #f9f9f9; + padding: 10px +} + +.navbar-nav > .user-menu > .dropdown-menu > .user-footer:before, .navbar-nav > .user-menu > .dropdown-menu > .user-footer:after { + content: " "; + display: table +} + +.navbar-nav > .user-menu > .dropdown-menu > .user-footer:after { + clear: both +} + +.navbar-nav > .user-menu > .dropdown-menu > .user-footer .btn-default { + color: #666666 +} + +@media (max-width: 991px) { + .navbar-nav > .user-menu > .dropdown-menu > .user-footer .btn-default:hover { + background-color: #f9f9f9 + } +} + +.navbar-nav > .user-menu .user-image { + float: left; + width: 25px; + height: 25px; + border-radius: 50%; + margin-right: 10px; + margin-top: -2px +} + +@media (max-width: 767px) { + .navbar-nav > .user-menu .user-image { + float: none; + margin-right: 0; + margin-top: -8px; + line-height: 10px + } +} + +.open:not(.dropup) > .animated-dropdown-menu { + backface-visibility: visible !important; + -webkit-animation: flipInX .7s both; + -o-animation: flipInX .7s both; + animation: flipInX .7s both +} + +@keyframes flipInX { + 0% { + transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + transition-timing-function: ease-in; + opacity: 0 + } + 40% { + transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + transition-timing-function: ease-in + } + 60% { + transform: perspective(400px) rotate3d(1, 0, 0, 10deg); + opacity: 1 + } + 80% { + transform: perspective(400px) rotate3d(1, 0, 0, -5deg) + } + 100% { + transform: perspective(400px) + } +} + +@-webkit-keyframes flipInX { + 0% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + -webkit-transition-timing-function: ease-in; + opacity: 0 + } + 40% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + -webkit-transition-timing-function: ease-in + } + 60% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg); + opacity: 1 + } + 80% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg) + } + 100% { + -webkit-transform: perspective(400px) + } +} + +.navbar-custom-menu > .navbar-nav > li { + position: relative +} + +.navbar-custom-menu > .navbar-nav > li > .dropdown-menu { + position: absolute; + right: 0; + left: auto +} + +@media (max-width: 991px) { + .navbar-custom-menu > .navbar-nav { + float: right + } + + .navbar-custom-menu > .navbar-nav > li { + position: static + } + + .navbar-custom-menu > .navbar-nav > li > .dropdown-menu { + position: absolute; + right: 5%; + left: auto; + border: 1px solid #ddd; + background: #fff + } +} + +.form-control { + border-radius: 0; + box-shadow: none; + border-color: #d2d6de +} + +.form-control:focus { + border-color: #3c8dbc; + box-shadow: none +} + +.form-control::-moz-placeholder, .form-control:-ms-input-placeholder, .form-control::-webkit-input-placeholder { + color: #bbb; + opacity: 1 +} + +.form-control:not(select) { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none +} + +.form-group.has-success label { + color: #00a65a +} + +.form-group.has-success .form-control, .form-group.has-success .input-group-addon { + border-color: #00a65a; + box-shadow: none +} + +.form-group.has-success .help-block { + color: #00a65a +} + +.form-group.has-warning label { + color: #f39c12 +} + +.form-group.has-warning .form-control, .form-group.has-warning .input-group-addon { + border-color: #f39c12; + box-shadow: none +} + +.form-group.has-warning .help-block { + color: #f39c12 +} + +.form-group.has-error label { + color: #dd4b39 +} + +.form-group.has-error .form-control, .form-group.has-error .input-group-addon { + border-color: #dd4b39; + box-shadow: none +} + +.form-group.has-error .help-block { + color: #dd4b39 +} + +.input-group .input-group-addon { + border-radius: 0; + border-color: #d2d6de; + background-color: #fff +} + +.btn-group-vertical .btn.btn-flat:first-of-type, .btn-group-vertical .btn.btn-flat:last-of-type { + border-radius: 0 +} + +.icheck > label { + padding-left: 0 +} + +.form-control-feedback.fa { + line-height: 34px +} + +.input-lg + .form-control-feedback.fa, .input-group-lg + .form-control-feedback.fa, .form-group-lg .form-control + .form-control-feedback.fa { + line-height: 46px +} + +.input-sm + .form-control-feedback.fa, .input-group-sm + .form-control-feedback.fa, .form-group-sm .form-control + .form-control-feedback.fa { + line-height: 30px +} + +.progress, .progress > .progress-bar { + -webkit-box-shadow: none; + box-shadow: none +} + +.progress, .progress > .progress-bar, .progress .progress-bar, .progress > .progress-bar .progress-bar { + border-radius: 1px +} + +.progress.sm, .progress-sm { + height: 10px +} + +.progress.sm, .progress-sm, .progress.sm .progress-bar, .progress-sm .progress-bar { + border-radius: 1px +} + +.progress.xs, .progress-xs { + height: 7px +} + +.progress.xs, .progress-xs, .progress.xs .progress-bar, .progress-xs .progress-bar { + border-radius: 1px +} + +.progress.xxs, .progress-xxs { + height: 3px +} + +.progress.xxs, .progress-xxs, .progress.xxs .progress-bar, .progress-xxs .progress-bar { + border-radius: 1px +} + +.progress.vertical { + position: relative; + width: 30px; + height: 200px; + display: inline-block; + margin-right: 10px +} + +.progress.vertical > .progress-bar { + width: 100%; + position: absolute; + bottom: 0 +} + +.progress.vertical.sm, .progress.vertical.progress-sm { + width: 20px +} + +.progress.vertical.xs, .progress.vertical.progress-xs { + width: 10px +} + +.progress.vertical.xxs, .progress.vertical.progress-xxs { + width: 3px +} + +.progress-group .progress-text { + font-weight: 600 +} + +.progress-group .progress-number { + float: right +} + +.table tr > td .progress { + margin: 0 +} + +.progress-bar-light-blue, .progress-bar-primary { + background-color: #3c8dbc +} + +.progress-striped .progress-bar-light-blue, .progress-striped .progress-bar-primary { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent) +} + +.progress-bar-green, .progress-bar-success { + background-color: #00a65a +} + +.progress-striped .progress-bar-green, .progress-striped .progress-bar-success { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent) +} + +.progress-bar-aqua, .progress-bar-info { + background-color: #00c0ef +} + +.progress-striped .progress-bar-aqua, .progress-striped .progress-bar-info { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent) +} + +.progress-bar-yellow, .progress-bar-warning { + background-color: #f39c12 +} + +.progress-striped .progress-bar-yellow, .progress-striped .progress-bar-warning { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent) +} + +.progress-bar-red, .progress-bar-danger { + background-color: #dd4b39 +} + +.progress-striped .progress-bar-red, .progress-striped .progress-bar-danger { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent) +} + +.small-box { + border-radius: 2px; + position: relative; + display: block; + margin-bottom: 20px; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1) +} + +.small-box > .inner { + padding: 10px +} + +.small-box > .small-box-footer { + position: relative; + text-align: center; + padding: 3px 0; + color: #fff; + color: rgba(255, 255, 255, 0.8); + display: block; + z-index: 10; + background: rgba(0, 0, 0, 0.1); + text-decoration: none +} + +.small-box > .small-box-footer:hover { + color: #fff; + background: rgba(0, 0, 0, 0.15) +} + +.small-box h3 { + font-size: 38px; + font-weight: bold; + margin: 0 0 10px 0; + white-space: nowrap; + padding: 0 +} + +.small-box p { + font-size: 15px +} + +.small-box p > small { + display: block; + color: #f9f9f9; + font-size: 13px; + margin-top: 5px +} + +.small-box h3, .small-box p { + z-index: 5 +} + +.small-box .icon { + -webkit-transition: all .3s linear; + -o-transition: all .3s linear; + transition: all .3s linear; + position: absolute; + top: -10px; + right: 10px; + z-index: 0; + font-size: 90px; + color: rgba(0, 0, 0, 0.15) +} + +.small-box:hover { + text-decoration: none; + color: #f9f9f9 +} + +.small-box:hover .icon { + font-size: 95px +} + +@media (max-width: 767px) { + .small-box { + text-align: center + } + + .small-box .icon { + display: none + } + + .small-box p { + font-size: 12px + } +} + +.box { + position: relative; + border-radius: 3px; + background: #ffffff; + border-top: 3px solid #d2d6de; + margin-bottom: 20px; + width: 100%; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1) +} + +.box.box-primary { + border-top-color: #3c8dbc +} + +.box.box-info { + border-top-color: #00c0ef +} + +.box.box-danger { + border-top-color: #dd4b39 +} + +.box.box-warning { + border-top-color: #f39c12 +} + +.box.box-success { + border-top-color: #00a65a +} + +.box.box-default { + border-top-color: #d2d6de +} + +.box.collapsed-box .box-body, .box.collapsed-box .box-footer { + display: none +} + +.box .nav-stacked > li { + border-bottom: 1px solid #f4f4f4; + margin: 0 +} + +.box .nav-stacked > li:last-of-type { + border-bottom: none +} + +.box.height-control .box-body { + max-height: 300px; + overflow: auto +} + +.box .border-right { + border-right: 1px solid #f4f4f4 +} + +.box .border-left { + border-left: 1px solid #f4f4f4 +} + +.box.box-solid { + border-top: 0 +} + +.box.box-solid > .box-header .btn.btn-default { + background: transparent +} + +.box.box-solid > .box-header .btn:hover, .box.box-solid > .box-header a:hover { + background: rgba(0, 0, 0, 0.1) +} + +.box.box-solid.box-default { + border: 1px solid #d2d6de +} + +.box.box-solid.box-default > .box-header { + color: #444; + background: #d2d6de; + background-color: #d2d6de +} + +.box.box-solid.box-default > .box-header a, .box.box-solid.box-default > .box-header .btn { + color: #444 +} + +.box.box-solid.box-primary { + border: 1px solid #3c8dbc +} + +.box.box-solid.box-primary > .box-header { + color: #fff; + background: #3c8dbc; + background-color: #3c8dbc +} + +.box.box-solid.box-primary > .box-header a, .box.box-solid.box-primary > .box-header .btn { + color: #fff +} + +.box.box-solid.box-info { + border: 1px solid #00c0ef +} + +.box.box-solid.box-info > .box-header { + color: #fff; + background: #00c0ef; + background-color: #00c0ef +} + +.box.box-solid.box-info > .box-header a, .box.box-solid.box-info > .box-header .btn { + color: #fff +} + +.box.box-solid.box-danger { + border: 1px solid #dd4b39 +} + +.box.box-solid.box-danger > .box-header { + color: #fff; + background: #dd4b39; + background-color: #dd4b39 +} + +.box.box-solid.box-danger > .box-header a, .box.box-solid.box-danger > .box-header .btn { + color: #fff +} + +.box.box-solid.box-warning { + border: 1px solid #f39c12 +} + +.box.box-solid.box-warning > .box-header { + color: #fff; + background: #f39c12; + background-color: #f39c12 +} + +.box.box-solid.box-warning > .box-header a, .box.box-solid.box-warning > .box-header .btn { + color: #fff +} + +.box.box-solid.box-success { + border: 1px solid #00a65a +} + +.box.box-solid.box-success > .box-header { + color: #fff; + background: #00a65a; + background-color: #00a65a +} + +.box.box-solid.box-success > .box-header a, .box.box-solid.box-success > .box-header .btn { + color: #fff +} + +.box.box-solid > .box-header > .box-tools .btn { + border: 0; + box-shadow: none +} + +.box.box-solid[class*='bg'] > .box-header { + color: #fff +} + +.box .box-group > .box { + margin-bottom: 5px +} + +.box .knob-label { + text-align: center; + color: #333; + font-weight: 100; + font-size: 12px; + margin-bottom: 0.3em +} + +.box > .overlay, .overlay-wrapper > .overlay, .box > .loading-img, .overlay-wrapper > .loading-img { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100% +} + +.box .overlay, .overlay-wrapper .overlay { + z-index: 50; + background: rgba(255, 255, 255, 0.7); + border-radius: 3px +} + +.box .overlay > .fa, .overlay-wrapper .overlay > .fa { + position: absolute; + top: 50%; + left: 50%; + margin-left: -15px; + margin-top: -15px; + color: #000; + font-size: 30px +} + +.box .overlay.dark, .overlay-wrapper .overlay.dark { + background: rgba(0, 0, 0, 0.5) +} + +.box-header:before, .box-body:before, .box-footer:before, .box-header:after, .box-body:after, .box-footer:after { + content: " "; + display: table +} + +.box-header:after, .box-body:after, .box-footer:after { + clear: both +} + +.box-header { + color: #444; + display: block; + padding: 10px; + position: relative +} + +.box-header.with-border { + border-bottom: 1px solid #f4f4f4 +} + +.collapsed-box .box-header.with-border { + border-bottom: none +} + +.box-header > .fa, .box-header > .glyphicon, .box-header > .ion, .box-header .box-title { + display: inline-block; + font-size: 18px; + margin: 0; + line-height: 1 +} + +.box-header > .fa, .box-header > .glyphicon, .box-header > .ion { + margin-right: 5px +} + +.box-header > .box-tools { + position: absolute; + right: 10px; + top: 5px +} + +.box-header > .box-tools [data-toggle="tooltip"] { + position: relative +} + +.box-header > .box-tools.pull-right .dropdown-menu { + right: 0; + left: auto +} + +.box-header > .box-tools .dropdown-menu > li > a { + color: #444 !important +} + +.btn-box-tool { + padding: 5px; + font-size: 12px; + background: transparent; + color: #97a0b3 +} + +.open .btn-box-tool, .btn-box-tool:hover { + color: #606c84 +} + +.btn-box-tool.btn:active { + box-shadow: none +} + +.box-body { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; + padding: 10px +} + +.no-header .box-body { + border-top-right-radius: 3px; + border-top-left-radius: 3px +} + +.box-body > .table { + margin-bottom: 0 +} + +.box-body .fc { + margin-top: 5px +} + +.box-body .full-width-chart { + margin: -19px +} + +.box-body.no-padding .full-width-chart { + margin: -9px +} + +.box-body .box-pane { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 3px +} + +.box-body .box-pane-right { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 0 +} + +.box-footer { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; + border-top: 1px solid #f4f4f4; + padding: 10px; + background-color: #fff +} + +.chart-legend { + margin: 10px 0 +} + +@media (max-width: 991px) { + .chart-legend > li { + float: left; + margin-right: 10px + } +} + +.box-comments { + background: #f7f7f7 +} + +.box-comments .box-comment { + padding: 8px 0; + border-bottom: 1px solid #eee +} + +.box-comments .box-comment:before, .box-comments .box-comment:after { + content: " "; + display: table +} + +.box-comments .box-comment:after { + clear: both +} + +.box-comments .box-comment:last-of-type { + border-bottom: 0 +} + +.box-comments .box-comment:first-of-type { + padding-top: 0 +} + +.box-comments .box-comment img { + float: left +} + +.box-comments .comment-text { + margin-left: 40px; + color: #555 +} + +.box-comments .username { + color: #444; + display: block; + font-weight: 600 +} + +.box-comments .text-muted { + font-weight: 400; + font-size: 12px +} + +.todo-list { + margin: 0; + padding: 0; + list-style: none; + overflow: auto +} + +.todo-list > li { + border-radius: 2px; + padding: 10px; + background: #f4f4f4; + margin-bottom: 2px; + border-left: 2px solid #e6e7e8; + color: #444 +} + +.todo-list > li:last-of-type { + margin-bottom: 0 +} + +.todo-list > li > input[type='checkbox'] { + margin: 0 10px 0 5px +} + +.todo-list > li .text { + display: inline-block; + margin-left: 5px; + font-weight: 600 +} + +.todo-list > li .label { + margin-left: 10px; + font-size: 9px +} + +.todo-list > li .tools { + display: none; + float: right; + color: #dd4b39 +} + +.todo-list > li .tools > .fa, .todo-list > li .tools > .glyphicon, .todo-list > li .tools > .ion { + margin-right: 5px; + cursor: pointer +} + +.todo-list > li:hover .tools { + display: inline-block +} + +.todo-list > li.done { + color: #999 +} + +.todo-list > li.done .text { + text-decoration: line-through; + font-weight: 500 +} + +.todo-list > li.done .label { + background: #d2d6de !important +} + +.todo-list .danger { + border-left-color: #dd4b39 +} + +.todo-list .warning { + border-left-color: #f39c12 +} + +.todo-list .info { + border-left-color: #00c0ef +} + +.todo-list .success { + border-left-color: #00a65a +} + +.todo-list .primary { + border-left-color: #3c8dbc +} + +.todo-list .handle { + display: inline-block; + cursor: move; + margin: 0 5px +} + +.chat { + padding: 5px 20px 5px 10px +} + +.chat .item { + margin-bottom: 10px +} + +.chat .item:before, .chat .item:after { + content: " "; + display: table +} + +.chat .item:after { + clear: both +} + +.chat .item > img { + width: 40px; + height: 40px; + border: 2px solid transparent; + border-radius: 50% +} + +.chat .item > .online { + border: 2px solid #00a65a +} + +.chat .item > .offline { + border: 2px solid #dd4b39 +} + +.chat .item > .message { + margin-left: 55px; + margin-top: -40px +} + +.chat .item > .message > .name { + display: block; + font-weight: 600 +} + +.chat .item > .attachment { + border-radius: 3px; + background: #f4f4f4; + margin-left: 65px; + margin-right: 15px; + padding: 10px +} + +.chat .item > .attachment > h4 { + margin: 0 0 5px 0; + font-weight: 600; + font-size: 14px +} + +.chat .item > .attachment > p, .chat .item > .attachment > .filename { + font-weight: 600; + font-size: 13px; + font-style: italic; + margin: 0 +} + +.chat .item > .attachment:before, .chat .item > .attachment:after { + content: " "; + display: table +} + +.chat .item > .attachment:after { + clear: both +} + +.box-input { + max-width: 200px +} + +.modal .panel-body { + color: #444 +} + +.info-box { + display: block; + min-height: 90px; + background: #fff; + width: 100%; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); + border-radius: 2px; + margin-bottom: 15px +} + +.info-box small { + font-size: 14px +} + +.info-box .progress { + background: rgba(0, 0, 0, 0.2); + margin: 5px -10px 5px -10px; + height: 2px +} + +.info-box .progress, .info-box .progress .progress-bar { + border-radius: 0 +} + +.info-box .progress .progress-bar { + background: #fff +} + +.info-box-icon { + border-top-left-radius: 2px; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 2px; + display: block; + float: left; + height: 90px; + width: 90px; + text-align: center; + font-size: 45px; + line-height: 90px; + background: rgba(0, 0, 0, 0.2) +} + +.info-box-icon > img { + max-width: 100% +} + +.info-box-content { + padding: 5px 10px; + margin-left: 90px +} + +.info-box-number { + display: block; + font-weight: bold; + font-size: 18px +} + +.progress-description, .info-box-text { + display: block; + font-size: 14px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis +} + +.info-box-text { + text-transform: uppercase +} + +.info-box-more { + display: block +} + +.progress-description { + margin: 0 +} + +.timeline { + position: relative; + margin: 0 0 30px 0; + padding: 0; + list-style: none +} + +.timeline:before { + content: ''; + position: absolute; + top: 0; + bottom: 0; + width: 4px; + background: #ddd; + left: 31px; + margin: 0; + border-radius: 2px +} + +.timeline > li { + position: relative; + margin-right: 10px; + margin-bottom: 15px +} + +.timeline > li:before, .timeline > li:after { + content: " "; + display: table +} + +.timeline > li:after { + clear: both +} + +.timeline > li > .timeline-item { + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); + border-radius: 3px; + margin-top: 0; + background: #fff; + color: #444; + margin-left: 60px; + margin-right: 15px; + padding: 0; + position: relative +} + +.timeline > li > .timeline-item > .time { + color: #999; + float: right; + padding: 10px; + font-size: 12px +} + +.timeline > li > .timeline-item > .timeline-header { + margin: 0; + color: #555; + border-bottom: 1px solid #f4f4f4; + padding: 10px; + font-size: 16px; + line-height: 1.1 +} + +.timeline > li > .timeline-item > .timeline-header > a { + font-weight: 600 +} + +.timeline > li > .timeline-item > .timeline-body, .timeline > li > .timeline-item > .timeline-footer { + padding: 10px +} + +.timeline > li > .fa, .timeline > li > .glyphicon, .timeline > li > .ion { + width: 30px; + height: 30px; + font-size: 15px; + line-height: 30px; + position: absolute; + color: #666; + background: #d2d6de; + border-radius: 50%; + text-align: center; + left: 18px; + top: 0 +} + +.timeline > .time-label > span { + font-weight: 600; + padding: 5px; + display: inline-block; + background-color: #fff; + border-radius: 4px +} + +.timeline-inverse > li > .timeline-item { + background: #f0f0f0; + border: 1px solid #ddd; + -webkit-box-shadow: none; + box-shadow: none +} + +.timeline-inverse > li > .timeline-item > .timeline-header { + border-bottom-color: #ddd +} + +.btn { + border-radius: 3px; + -webkit-box-shadow: none; + box-shadow: none; + border: 1px solid transparent +} + +.btn.uppercase { + text-transform: uppercase +} + +.btn.btn-flat { + border-radius: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + border-width: 1px +} + +.btn:active { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + -moz-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125) +} + +.btn:focus { + outline: none +} + +.btn.btn-file { + position: relative; + overflow: hidden +} + +.btn.btn-file > input[type='file'] { + position: absolute; + top: 0; + right: 0; + min-width: 100%; + min-height: 100%; + font-size: 100px; + text-align: right; + opacity: 0; + filter: alpha(opacity=0); + outline: none; + background: white; + cursor: inherit; + display: block +} + +.btn-default { + background-color: #f4f4f4; + color: #444; + border-color: #ddd +} + +.btn-default:hover, .btn-default:active, .btn-default.hover { + background-color: #e7e7e7 +} + +.btn-primary { + background-color: #3c8dbc; + border-color: #367fa9 +} + +.btn-primary:hover, .btn-primary:active, .btn-primary.hover { + background-color: #367fa9 +} + +.btn-success { + background-color: #00a65a; + border-color: #008d4c +} + +.btn-success:hover, .btn-success:active, .btn-success.hover { + background-color: #008d4c +} + +.btn-info { + background-color: #00c0ef; + border-color: #00acd6 +} + +.btn-info:hover, .btn-info:active, .btn-info.hover { + background-color: #00acd6 +} + +.btn-danger { + background-color: #dd4b39; + border-color: #d73925 +} + +.btn-danger:hover, .btn-danger:active, .btn-danger.hover { + background-color: #d73925 +} + +.btn-warning { + background-color: #f39c12; + border-color: #e08e0b +} + +.btn-warning:hover, .btn-warning:active, .btn-warning.hover { + background-color: #e08e0b +} + +.btn-outline { + border: 1px solid #fff; + background: transparent; + color: #fff +} + +.btn-outline:hover, .btn-outline:focus, .btn-outline:active { + color: rgba(255, 255, 255, 0.7); + border-color: rgba(255, 255, 255, 0.7) +} + +.btn-link { + -webkit-box-shadow: none; + box-shadow: none +} + +.btn[class*='bg-']:hover { + -webkit-box-shadow: inset 0 0 100px rgba(0, 0, 0, 0.2); + box-shadow: inset 0 0 100px rgba(0, 0, 0, 0.2) +} + +.btn-app { + border-radius: 3px; + position: relative; + padding: 15px 5px; + margin: 0 0 10px 10px; + min-width: 80px; + height: 60px; + text-align: center; + color: #666; + border: 1px solid #ddd; + background-color: #f4f4f4; + font-size: 12px +} + +.btn-app > .fa, .btn-app > .glyphicon, .btn-app > .ion { + font-size: 20px; + display: block +} + +.btn-app:hover { + background: #f4f4f4; + color: #444; + border-color: #aaa +} + +.btn-app:active, .btn-app:focus { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + -moz-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125) +} + +.btn-app > .badge { + position: absolute; + top: -3px; + right: -10px; + font-size: 10px; + font-weight: 400 +} + +.callout { + border-radius: 3px; + margin: 0 0 20px 0; + padding: 15px 30px 15px 15px; + border-left: 5px solid #eee +} + +.callout a { + color: #fff; + text-decoration: underline +} + +.callout a:hover { + color: #eee +} + +.callout h4 { + margin-top: 0; + font-weight: 600 +} + +.callout p:last-child { + margin-bottom: 0 +} + +.callout code, .callout .highlight { + background-color: #fff +} + +.callout.callout-danger { + border-color: #c23321 +} + +.callout.callout-warning { + border-color: #c87f0a +} + +.callout.callout-info { + border-color: #0097bc +} + +.callout.callout-success { + border-color: #00733e +} + +.alert { + border-radius: 3px +} + +.alert h4 { + font-weight: 600 +} + +.alert .icon { + margin-right: 10px +} + +.alert .close { + color: #000; + opacity: .2; + filter: alpha(opacity=20) +} + +.alert .close:hover { + opacity: .5; + filter: alpha(opacity=50) +} + +.alert a { + color: #fff; + text-decoration: underline +} + +.alert-success { + border-color: #008d4c +} + +.alert-danger, .alert-error { + border-color: #d73925 +} + +.alert-warning { + border-color: #e08e0b +} + +.alert-info { + border-color: #00acd6 +} + +.nav > li > a:hover, .nav > li > a:active, .nav > li > a:focus { + color: #444; + background: #f7f7f7 +} + +.nav-pills > li > a { + border-radius: 0; + border-top: 3px solid transparent; + color: #444 +} + +.nav-pills > li > a > .fa, .nav-pills > li > a > .glyphicon, .nav-pills > li > a > .ion { + margin-right: 5px +} + +.nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus { + border-top-color: #3c8dbc +} + +.nav-pills > li.active > a { + font-weight: 600 +} + +.nav-stacked > li > a { + border-radius: 0; + border-top: 0; + border-left: 3px solid transparent; + color: #444 +} + +.nav-stacked > li.active > a, .nav-stacked > li.active > a:hover { + background: transparent; + color: #444; + border-top: 0; + border-left-color: #3c8dbc +} + +.nav-stacked > li.header { + border-bottom: 1px solid #ddd; + color: #777; + margin-bottom: 10px; + padding: 5px 10px; + text-transform: uppercase +} + +.nav-tabs-custom { + margin-bottom: 20px; + background: #fff; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); + border-radius: 3px +} + +.nav-tabs-custom > .nav-tabs { + margin: 0; + border-bottom-color: #f4f4f4; + border-top-right-radius: 3px; + border-top-left-radius: 3px +} + +.nav-tabs-custom > .nav-tabs > li { + border-top: 3px solid transparent; + margin-bottom: -2px; + margin-right: 5px +} + +.nav-tabs-custom > .nav-tabs > li > a { + color: #444; + border-radius: 0 +} + +.nav-tabs-custom > .nav-tabs > li > a.text-muted { + color: #999 +} + +.nav-tabs-custom > .nav-tabs > li > a, .nav-tabs-custom > .nav-tabs > li > a:hover { + background: transparent; + margin: 0 +} + +.nav-tabs-custom > .nav-tabs > li > a:hover { + color: #999 +} + +.nav-tabs-custom > .nav-tabs > li:not(.active) > a:hover, .nav-tabs-custom > .nav-tabs > li:not(.active) > a:focus, .nav-tabs-custom > .nav-tabs > li:not(.active) > a:active { + border-color: transparent +} + +.nav-tabs-custom > .nav-tabs > li.active { + border-top-color: #3c8dbc +} + +.nav-tabs-custom > .nav-tabs > li.active > a, .nav-tabs-custom > .nav-tabs > li.active:hover > a { + background-color: #fff; + color: #444 +} + +.nav-tabs-custom > .nav-tabs > li.active > a { + border-top-color: transparent; + border-left-color: #f4f4f4; + border-right-color: #f4f4f4 +} + +.nav-tabs-custom > .nav-tabs > li:first-of-type { + margin-left: 0 +} + +.nav-tabs-custom > .nav-tabs > li:first-of-type.active > a { + border-left-color: transparent +} + +.nav-tabs-custom > .nav-tabs.pull-right { + float: none !important +} + +.nav-tabs-custom > .nav-tabs.pull-right > li { + float: right +} + +.nav-tabs-custom > .nav-tabs.pull-right > li:first-of-type { + margin-right: 0 +} + +.nav-tabs-custom > .nav-tabs.pull-right > li:first-of-type > a { + border-left-width: 1px +} + +.nav-tabs-custom > .nav-tabs.pull-right > li:first-of-type.active > a { + border-left-color: #f4f4f4; + border-right-color: transparent +} + +.nav-tabs-custom > .nav-tabs > li.header { + line-height: 35px; + padding: 0 10px; + font-size: 20px; + color: #444 +} + +.nav-tabs-custom > .nav-tabs > li.header > .fa, .nav-tabs-custom > .nav-tabs > li.header > .glyphicon, .nav-tabs-custom > .nav-tabs > li.header > .ion { + margin-right: 5px +} + +.nav-tabs-custom > .tab-content { + background: #fff; + padding: 10px; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px +} + +.nav-tabs-custom .dropdown.open > a:active, .nav-tabs-custom .dropdown.open > a:focus { + background: transparent; + color: #999 +} + +.nav-tabs-custom.tab-primary > .nav-tabs > li.active { + border-top-color: #3c8dbc +} + +.nav-tabs-custom.tab-info > .nav-tabs > li.active { + border-top-color: #00c0ef +} + +.nav-tabs-custom.tab-danger > .nav-tabs > li.active { + border-top-color: #dd4b39 +} + +.nav-tabs-custom.tab-warning > .nav-tabs > li.active { + border-top-color: #f39c12 +} + +.nav-tabs-custom.tab-success > .nav-tabs > li.active { + border-top-color: #00a65a +} + +.nav-tabs-custom.tab-default > .nav-tabs > li.active { + border-top-color: #d2d6de +} + +.pagination > li > a { + background: #fafafa; + color: #666 +} + +.pagination.pagination-flat > li > a { + border-radius: 0 !important +} + +.products-list { + list-style: none; + margin: 0; + padding: 0 +} + +.products-list > .item { + border-radius: 3px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); + padding: 10px 0; + background: #fff +} + +.products-list > .item:before, .products-list > .item:after { + content: " "; + display: table +} + +.products-list > .item:after { + clear: both +} + +.products-list .product-img { + float: left +} + +.products-list .product-img img { + width: 50px; + height: 50px +} + +.products-list .product-info { + margin-left: 60px +} + +.products-list .product-title { + font-weight: 600 +} + +.products-list .product-description { + display: block; + color: #999; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis +} + +.product-list-in-box > .item { + -webkit-box-shadow: none; + box-shadow: none; + border-radius: 0; + border-bottom: 1px solid #f4f4f4 +} + +.product-list-in-box > .item:last-of-type { + border-bottom-width: 0 +} + +.table > thead > tr > th, .table > tbody > tr > th, .table > tfoot > tr > th, .table > thead > tr > td, .table > tbody > tr > td, .table > tfoot > tr > td { + border-top: 1px solid #f4f4f4 +} + +.table > thead > tr > th { + border-bottom: 2px solid #f4f4f4 +} + +.table tr td .progress { + margin-top: 5px +} + +.table-bordered { + border: 1px solid #f4f4f4 +} + +.table-bordered > thead > tr > th, .table-bordered > tbody > tr > th, .table-bordered > tfoot > tr > th, .table-bordered > thead > tr > td, .table-bordered > tbody > tr > td, .table-bordered > tfoot > tr > td { + border: 1px solid #f4f4f4 +} + +.table-bordered > thead > tr > th, .table-bordered > thead > tr > td { + border-bottom-width: 2px +} + +.table.no-border, .table.no-border td, .table.no-border th { + border: 0 +} + +table.text-center, table.text-center td, table.text-center th { + text-align: center +} + +.table.align th { + text-align: left +} + +.table.align td { + text-align: right +} + +.label-default { + background-color: #d2d6de; + color: #444 +} + +.direct-chat .box-body { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + position: relative; + overflow-x: hidden; + padding: 0 +} + +.direct-chat.chat-pane-open .direct-chat-contacts { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0) +} + +.direct-chat-messages { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0); + padding: 10px; + height: 250px; + overflow: auto +} + +.direct-chat-msg, .direct-chat-text { + display: block +} + +.direct-chat-msg { + margin-bottom: 10px +} + +.direct-chat-msg:before, .direct-chat-msg:after { + content: " "; + display: table +} + +.direct-chat-msg:after { + clear: both +} + +.direct-chat-messages, .direct-chat-contacts { + -webkit-transition: -webkit-transform .5s ease-in-out; + -moz-transition: -moz-transform .5s ease-in-out; + -o-transition: -o-transform .5s ease-in-out; + transition: transform .5s ease-in-out +} + +.direct-chat-text { + border-radius: 5px; + position: relative; + padding: 5px 10px; + background: #d2d6de; + border: 1px solid #d2d6de; + margin: 5px 0 0 50px; + color: #444 +} + +.direct-chat-text:after, .direct-chat-text:before { + position: absolute; + right: 100%; + top: 15px; + border: solid transparent; + border-right-color: #d2d6de; + content: ' '; + height: 0; + width: 0; + pointer-events: none +} + +.direct-chat-text:after { + border-width: 5px; + margin-top: -5px +} + +.direct-chat-text:before { + border-width: 6px; + margin-top: -6px +} + +.right .direct-chat-text { + margin-right: 50px; + margin-left: 0 +} + +.right .direct-chat-text:after, .right .direct-chat-text:before { + right: auto; + left: 100%; + border-right-color: transparent; + border-left-color: #d2d6de +} + +.direct-chat-img { + border-radius: 50%; + float: left; + width: 40px; + height: 40px +} + +.right .direct-chat-img { + float: right +} + +.direct-chat-info { + display: block; + margin-bottom: 2px; + font-size: 12px +} + +.direct-chat-name { + font-weight: 600 +} + +.direct-chat-timestamp { + color: #999 +} + +.direct-chat-contacts-open .direct-chat-contacts { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0) +} + +.direct-chat-contacts { + -webkit-transform: translate(101%, 0); + -ms-transform: translate(101%, 0); + -o-transform: translate(101%, 0); + transform: translate(101%, 0); + position: absolute; + top: 0; + bottom: 0; + height: 250px; + width: 100%; + background: #222d32; + color: #fff; + overflow: auto +} + +.contacts-list > li { + border-bottom: 1px solid rgba(0, 0, 0, 0.2); + padding: 10px; + margin: 0 +} + +.contacts-list > li:before, .contacts-list > li:after { + content: " "; + display: table +} + +.contacts-list > li:after { + clear: both +} + +.contacts-list > li:last-of-type { + border-bottom: none +} + +.contacts-list-img { + border-radius: 50%; + width: 40px; + float: left +} + +.contacts-list-info { + margin-left: 45px; + color: #fff +} + +.contacts-list-name, .contacts-list-status { + display: block +} + +.contacts-list-name { + font-weight: 600 +} + +.contacts-list-status { + font-size: 12px +} + +.contacts-list-date { + color: #aaa; + font-weight: normal +} + +.contacts-list-msg { + color: #999 +} + +.direct-chat-danger .right > .direct-chat-text { + background: #dd4b39; + border-color: #dd4b39; + color: #fff +} + +.direct-chat-danger .right > .direct-chat-text:after, .direct-chat-danger .right > .direct-chat-text:before { + border-left-color: #dd4b39 +} + +.direct-chat-primary .right > .direct-chat-text { + background: #3c8dbc; + border-color: #3c8dbc; + color: #fff +} + +.direct-chat-primary .right > .direct-chat-text:after, .direct-chat-primary .right > .direct-chat-text:before { + border-left-color: #3c8dbc +} + +.direct-chat-warning .right > .direct-chat-text { + background: #f39c12; + border-color: #f39c12; + color: #fff +} + +.direct-chat-warning .right > .direct-chat-text:after, .direct-chat-warning .right > .direct-chat-text:before { + border-left-color: #f39c12 +} + +.direct-chat-info .right > .direct-chat-text { + background: #00c0ef; + border-color: #00c0ef; + color: #fff +} + +.direct-chat-info .right > .direct-chat-text:after, .direct-chat-info .right > .direct-chat-text:before { + border-left-color: #00c0ef +} + +.direct-chat-success .right > .direct-chat-text { + background: #00a65a; + border-color: #00a65a; + color: #fff +} + +.direct-chat-success .right > .direct-chat-text:after, .direct-chat-success .right > .direct-chat-text:before { + border-left-color: #00a65a +} + +.users-list > li { + width: 25%; + float: left; + padding: 10px; + text-align: center +} + +.users-list > li img { + border-radius: 50%; + max-width: 100%; + height: auto +} + +.users-list > li > a:hover, .users-list > li > a:hover .users-list-name { + color: #999 +} + +.users-list-name, .users-list-date { + display: block +} + +.users-list-name { + font-weight: 600; + color: #444; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis +} + +.users-list-date { + color: #999; + font-size: 12px +} + +.carousel-control.left, .carousel-control.right { + background-image: none +} + +.carousel-control > .fa { + font-size: 40px; + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; + margin-top: -20px +} + +.modal { + background: rgba(0, 0, 0, 0.3) +} + +.modal-content { + border-radius: 0; + -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.125); + box-shadow: 0 2px 3px rgba(0, 0, 0, 0.125); + border: 0 +} + +@media (min-width: 768px) { + .modal-content { + -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.125); + box-shadow: 0 2px 3px rgba(0, 0, 0, 0.125) + } +} + +.modal-header { + border-bottom-color: #f4f4f4 +} + +.modal-footer { + border-top-color: #f4f4f4 +} + +.modal-primary .modal-header, .modal-primary .modal-footer { + border-color: #307095 +} + +.modal-warning .modal-header, .modal-warning .modal-footer { + border-color: #c87f0a +} + +.modal-info .modal-header, .modal-info .modal-footer { + border-color: #0097bc +} + +.modal-success .modal-header, .modal-success .modal-footer { + border-color: #00733e +} + +.modal-danger .modal-header, .modal-danger .modal-footer { + border-color: #c23321 +} + +.box-widget { + border: none; + position: relative +} + +.widget-user .widget-user-header { + padding: 20px; + height: 120px; + border-top-right-radius: 3px; + border-top-left-radius: 3px +} + +.widget-user .widget-user-username { + margin-top: 0; + margin-bottom: 5px; + font-size: 25px; + font-weight: 300; + text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2) +} + +.widget-user .widget-user-desc { + margin-top: 0 +} + +.widget-user .widget-user-image { + position: absolute; + top: 65px; + left: 50%; + margin-left: -45px +} + +.widget-user .widget-user-image > img { + width: 90px; + height: auto; + border: 3px solid #fff +} + +.widget-user .box-footer { + padding-top: 30px +} + +.widget-user-2 .widget-user-header { + padding: 20px; + border-top-right-radius: 3px; + border-top-left-radius: 3px +} + +.widget-user-2 .widget-user-username { + margin-top: 5px; + margin-bottom: 5px; + font-size: 25px; + font-weight: 300 +} + +.widget-user-2 .widget-user-desc { + margin-top: 0 +} + +.widget-user-2 .widget-user-username, .widget-user-2 .widget-user-desc { + margin-left: 75px +} + +.widget-user-2 .widget-user-image > img { + width: 65px; + height: auto; + float: left +} + +.mailbox-messages > .table { + margin: 0 +} + +.mailbox-controls { + padding: 5px +} + +.mailbox-controls.with-border { + border-bottom: 1px solid #f4f4f4 +} + +.mailbox-read-info { + border-bottom: 1px solid #f4f4f4; + padding: 10px +} + +.mailbox-read-info h3 { + font-size: 20px; + margin: 0 +} + +.mailbox-read-info h5 { + margin: 0; + padding: 5px 0 0 0 +} + +.mailbox-read-time { + color: #999; + font-size: 13px +} + +.mailbox-read-message { + padding: 10px +} + +.mailbox-attachments li { + float: left; + width: 200px; + border: 1px solid #eee; + margin-bottom: 10px; + margin-right: 10px +} + +.mailbox-attachment-name { + font-weight: bold; + color: #666 +} + +.mailbox-attachment-icon, .mailbox-attachment-info, .mailbox-attachment-size { + display: block +} + +.mailbox-attachment-info { + padding: 10px; + background: #f4f4f4 +} + +.mailbox-attachment-size { + color: #999; + font-size: 12px +} + +.mailbox-attachment-icon { + text-align: center; + font-size: 65px; + color: #666; + padding: 20px 10px +} + +.mailbox-attachment-icon.has-img { + padding: 0 +} + +.mailbox-attachment-icon.has-img > img { + max-width: 100%; + height: auto +} + +.lockscreen { + background: #d2d6de +} + +.lockscreen-logo { + font-size: 35px; + text-align: center; + margin-bottom: 25px; + font-weight: 300 +} + +.lockscreen-logo a { + color: #444 +} + +.lockscreen-wrapper { + max-width: 400px; + margin: 0 auto; + margin-top: 10% +} + +.lockscreen .lockscreen-name { + text-align: center; + font-weight: 600 +} + +.lockscreen-item { + border-radius: 4px; + padding: 0; + background: #fff; + position: relative; + margin: 10px auto 30px auto; + width: 290px +} + +.lockscreen-image { + border-radius: 50%; + position: absolute; + left: -10px; + top: -25px; + background: #fff; + padding: 5px; + z-index: 10 +} + +.lockscreen-image > img { + border-radius: 50%; + width: 70px; + height: 70px +} + +.lockscreen-credentials { + margin-left: 70px +} + +.lockscreen-credentials .form-control { + border: 0 +} + +.lockscreen-credentials .btn { + background-color: #fff; + border: 0; + padding: 0 10px +} + +.lockscreen-footer { + margin-top: 10px +} + +.login-logo, .register-logo { + font-size: 35px; + text-align: center; + margin-bottom: 25px; + font-weight: 300 +} + +.login-logo a, .register-logo a { + color: #444 +} + +.login-page, .register-page { + background-image: url("../img/logoin-background.png"); + background-size:100%; +} + +.login-box, .register-box { + width: 360px; + margin: 7% auto +} + +@media (max-width: 768px) { + .login-box, .register-box { + width: 90%; + margin-top: 20px + } +} + +.login-box-body, .register-box-body { + background: #fff; + padding: 20px; + border-top: 0; + color: #666 +} + +.login-box-body .form-control-feedback, .register-box-body .form-control-feedback { + color: #777 +} + +.login-box-msg, .register-box-msg { + margin: 0; + text-align: center; + padding: 0 20px 20px 20px +} + +.social-auth-links { + margin: 10px 0 +} + +.error-page { + width: 600px; + margin: 20px auto 0 auto +} + +@media (max-width: 991px) { + .error-page { + width: 100% + } +} + +.error-page > .headline { + float: left; + font-size: 100px; + font-weight: 300 +} + +@media (max-width: 991px) { + .error-page > .headline { + float: none; + text-align: center + } +} + +.error-page > .error-content { + margin-left: 190px; + display: block +} + +@media (max-width: 991px) { + .error-page > .error-content { + margin-left: 0 + } +} + +.error-page > .error-content > h3 { + font-weight: 300; + font-size: 25px +} + +@media (max-width: 991px) { + .error-page > .error-content > h3 { + text-align: center + } +} + +.invoice { + position: relative; + background: #fff; + border: 1px solid #f4f4f4; + padding: 20px; + margin: 10px 25px +} + +.invoice-title { + margin-top: 0 +} + +.profile-user-img { + margin: 0 auto; + width: 100px; + padding: 3px; + border: 3px solid #d2d6de +} + +.profile-username { + font-size: 21px; + margin-top: 5px +} + +.post { + border-bottom: 1px solid #d2d6de; + margin-bottom: 15px; + padding-bottom: 15px; + color: #666 +} + +.post:last-of-type { + border-bottom: 0; + margin-bottom: 0; + padding-bottom: 0 +} + +.post .user-block { + margin-bottom: 15px +} + +.btn-social { + position: relative; + padding-left: 44px; + text-align: left; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis +} + +.btn-social > :first-child { + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: 32px; + line-height: 34px; + font-size: 1.6em; + text-align: center; + border-right: 1px solid rgba(0, 0, 0, 0.2) +} + +.btn-social.btn-lg { + padding-left: 61px +} + +.btn-social.btn-lg > :first-child { + line-height: 45px; + width: 45px; + font-size: 1.8em +} + +.btn-social.btn-sm { + padding-left: 38px +} + +.btn-social.btn-sm > :first-child { + line-height: 28px; + width: 28px; + font-size: 1.4em +} + +.btn-social.btn-xs { + padding-left: 30px +} + +.btn-social.btn-xs > :first-child { + line-height: 20px; + width: 20px; + font-size: 1.2em +} + +.btn-social-icon { + position: relative; + padding-left: 44px; + text-align: left; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + height: 34px; + width: 34px; + padding: 0 +} + +.btn-social-icon > :first-child { + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: 32px; + line-height: 34px; + font-size: 1.6em; + text-align: center; + border-right: 1px solid rgba(0, 0, 0, 0.2) +} + +.btn-social-icon.btn-lg { + padding-left: 61px +} + +.btn-social-icon.btn-lg > :first-child { + line-height: 45px; + width: 45px; + font-size: 1.8em +} + +.btn-social-icon.btn-sm { + padding-left: 38px +} + +.btn-social-icon.btn-sm > :first-child { + line-height: 28px; + width: 28px; + font-size: 1.4em +} + +.btn-social-icon.btn-xs { + padding-left: 30px +} + +.btn-social-icon.btn-xs > :first-child { + line-height: 20px; + width: 20px; + font-size: 1.2em +} + +.btn-social-icon > :first-child { + border: none; + text-align: center; + width: 100% +} + +.btn-social-icon.btn-lg { + height: 45px; + width: 45px; + padding-left: 0; + padding-right: 0 +} + +.btn-social-icon.btn-sm { + height: 30px; + width: 30px; + padding-left: 0; + padding-right: 0 +} + +.btn-social-icon.btn-xs { + height: 22px; + width: 22px; + padding-left: 0; + padding-right: 0 +} + +.btn-adn { + color: #fff; + background-color: #d87a68; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-adn:focus, .btn-adn.focus { + color: #fff; + background-color: #ce563f; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-adn:hover { + color: #fff; + background-color: #ce563f; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-adn:active, .btn-adn.active, .open > .dropdown-toggle.btn-adn { + color: #fff; + background-color: #ce563f; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-adn:active, .btn-adn.active, .open > .dropdown-toggle.btn-adn { + background-image: none +} + +.btn-adn .badge { + color: #d87a68; + background-color: #fff +} + +.btn-bitbucket { + color: #fff; + background-color: #205081; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-bitbucket:focus, .btn-bitbucket.focus { + color: #fff; + background-color: #163758; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-bitbucket:hover { + color: #fff; + background-color: #163758; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-bitbucket:active, .btn-bitbucket.active, .open > .dropdown-toggle.btn-bitbucket { + color: #fff; + background-color: #163758; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-bitbucket:active, .btn-bitbucket.active, .open > .dropdown-toggle.btn-bitbucket { + background-image: none +} + +.btn-bitbucket .badge { + color: #205081; + background-color: #fff +} + +.btn-dropbox { + color: #fff; + background-color: #1087dd; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-dropbox:focus, .btn-dropbox.focus { + color: #fff; + background-color: #0d6aad; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-dropbox:hover { + color: #fff; + background-color: #0d6aad; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-dropbox:active, .btn-dropbox.active, .open > .dropdown-toggle.btn-dropbox { + color: #fff; + background-color: #0d6aad; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-dropbox:active, .btn-dropbox.active, .open > .dropdown-toggle.btn-dropbox { + background-image: none +} + +.btn-dropbox .badge { + color: #1087dd; + background-color: #fff +} + +.btn-facebook { + color: #fff; + background-color: #3b5998; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-facebook:focus, .btn-facebook.focus { + color: #fff; + background-color: #2d4373; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-facebook:hover { + color: #fff; + background-color: #2d4373; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-facebook:active, .btn-facebook.active, .open > .dropdown-toggle.btn-facebook { + color: #fff; + background-color: #2d4373; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-facebook:active, .btn-facebook.active, .open > .dropdown-toggle.btn-facebook { + background-image: none +} + +.btn-facebook .badge { + color: #3b5998; + background-color: #fff +} + +.btn-flickr { + color: #fff; + background-color: #ff0084; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-flickr:focus, .btn-flickr.focus { + color: #fff; + background-color: #cc006a; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-flickr:hover { + color: #fff; + background-color: #cc006a; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-flickr:active, .btn-flickr.active, .open > .dropdown-toggle.btn-flickr { + color: #fff; + background-color: #cc006a; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-flickr:active, .btn-flickr.active, .open > .dropdown-toggle.btn-flickr { + background-image: none +} + +.btn-flickr .badge { + color: #ff0084; + background-color: #fff +} + +.btn-foursquare { + color: #fff; + background-color: #f94877; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-foursquare:focus, .btn-foursquare.focus { + color: #fff; + background-color: #f71752; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-foursquare:hover { + color: #fff; + background-color: #f71752; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-foursquare:active, .btn-foursquare.active, .open > .dropdown-toggle.btn-foursquare { + color: #fff; + background-color: #f71752; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-foursquare:active, .btn-foursquare.active, .open > .dropdown-toggle.btn-foursquare { + background-image: none +} + +.btn-foursquare .badge { + color: #f94877; + background-color: #fff +} + +.btn-github { + color: #fff; + background-color: #444; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-github:focus, .btn-github.focus { + color: #fff; + background-color: #2b2b2b; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-github:hover { + color: #fff; + background-color: #2b2b2b; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-github:active, .btn-github.active, .open > .dropdown-toggle.btn-github { + color: #fff; + background-color: #2b2b2b; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-github:active, .btn-github.active, .open > .dropdown-toggle.btn-github { + background-image: none +} + +.btn-github .badge { + color: #444; + background-color: #fff +} + +.btn-google { + color: #fff; + background-color: #dd4b39; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-google:focus, .btn-google.focus { + color: #fff; + background-color: #c23321; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-google:hover { + color: #fff; + background-color: #c23321; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-google:active, .btn-google.active, .open > .dropdown-toggle.btn-google { + color: #fff; + background-color: #c23321; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-google:active, .btn-google.active, .open > .dropdown-toggle.btn-google { + background-image: none +} + +.btn-google .badge { + color: #dd4b39; + background-color: #fff +} + +.btn-instagram { + color: #fff; + background-color: #3f729b; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-instagram:focus, .btn-instagram.focus { + color: #fff; + background-color: #305777; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-instagram:hover { + color: #fff; + background-color: #305777; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-instagram:active, .btn-instagram.active, .open > .dropdown-toggle.btn-instagram { + color: #fff; + background-color: #305777; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-instagram:active, .btn-instagram.active, .open > .dropdown-toggle.btn-instagram { + background-image: none +} + +.btn-instagram .badge { + color: #3f729b; + background-color: #fff +} + +.btn-linkedin { + color: #fff; + background-color: #007bb6; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-linkedin:focus, .btn-linkedin.focus { + color: #fff; + background-color: #005983; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-linkedin:hover { + color: #fff; + background-color: #005983; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-linkedin:active, .btn-linkedin.active, .open > .dropdown-toggle.btn-linkedin { + color: #fff; + background-color: #005983; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-linkedin:active, .btn-linkedin.active, .open > .dropdown-toggle.btn-linkedin { + background-image: none +} + +.btn-linkedin .badge { + color: #007bb6; + background-color: #fff +} + +.btn-microsoft { + color: #fff; + background-color: #2672ec; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-microsoft:focus, .btn-microsoft.focus { + color: #fff; + background-color: #125acd; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-microsoft:hover { + color: #fff; + background-color: #125acd; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-microsoft:active, .btn-microsoft.active, .open > .dropdown-toggle.btn-microsoft { + color: #fff; + background-color: #125acd; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-microsoft:active, .btn-microsoft.active, .open > .dropdown-toggle.btn-microsoft { + background-image: none +} + +.btn-microsoft .badge { + color: #2672ec; + background-color: #fff +} + +.btn-openid { + color: #fff; + background-color: #f7931e; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-openid:focus, .btn-openid.focus { + color: #fff; + background-color: #da7908; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-openid:hover { + color: #fff; + background-color: #da7908; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-openid:active, .btn-openid.active, .open > .dropdown-toggle.btn-openid { + color: #fff; + background-color: #da7908; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-openid:active, .btn-openid.active, .open > .dropdown-toggle.btn-openid { + background-image: none +} + +.btn-openid .badge { + color: #f7931e; + background-color: #fff +} + +.btn-pinterest { + color: #fff; + background-color: #cb2027; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-pinterest:focus, .btn-pinterest.focus { + color: #fff; + background-color: #9f191f; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-pinterest:hover { + color: #fff; + background-color: #9f191f; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-pinterest:active, .btn-pinterest.active, .open > .dropdown-toggle.btn-pinterest { + color: #fff; + background-color: #9f191f; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-pinterest:active, .btn-pinterest.active, .open > .dropdown-toggle.btn-pinterest { + background-image: none +} + +.btn-pinterest .badge { + color: #cb2027; + background-color: #fff +} + +.btn-reddit { + color: #000; + background-color: #eff7ff; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-reddit:focus, .btn-reddit.focus { + color: #000; + background-color: #bcddff; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-reddit:hover { + color: #000; + background-color: #bcddff; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-reddit:active, .btn-reddit.active, .open > .dropdown-toggle.btn-reddit { + color: #000; + background-color: #bcddff; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-reddit:active, .btn-reddit.active, .open > .dropdown-toggle.btn-reddit { + background-image: none +} + +.btn-reddit .badge { + color: #eff7ff; + background-color: #000 +} + +.btn-soundcloud { + color: #fff; + background-color: #f50; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-soundcloud:focus, .btn-soundcloud.focus { + color: #fff; + background-color: #c40; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-soundcloud:hover { + color: #fff; + background-color: #c40; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-soundcloud:active, .btn-soundcloud.active, .open > .dropdown-toggle.btn-soundcloud { + color: #fff; + background-color: #c40; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-soundcloud:active, .btn-soundcloud.active, .open > .dropdown-toggle.btn-soundcloud { + background-image: none +} + +.btn-soundcloud .badge { + color: #f50; + background-color: #fff +} + +.btn-tumblr { + color: #fff; + background-color: #2c4762; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-tumblr:focus, .btn-tumblr.focus { + color: #fff; + background-color: #1c2d3f; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-tumblr:hover { + color: #fff; + background-color: #1c2d3f; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-tumblr:active, .btn-tumblr.active, .open > .dropdown-toggle.btn-tumblr { + color: #fff; + background-color: #1c2d3f; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-tumblr:active, .btn-tumblr.active, .open > .dropdown-toggle.btn-tumblr { + background-image: none +} + +.btn-tumblr .badge { + color: #2c4762; + background-color: #fff +} + +.btn-twitter { + color: #fff; + background-color: #55acee; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-twitter:focus, .btn-twitter.focus { + color: #fff; + background-color: #2795e9; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-twitter:hover { + color: #fff; + background-color: #2795e9; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-twitter:active, .btn-twitter.active, .open > .dropdown-toggle.btn-twitter { + color: #fff; + background-color: #2795e9; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-twitter:active, .btn-twitter.active, .open > .dropdown-toggle.btn-twitter { + background-image: none +} + +.btn-twitter .badge { + color: #55acee; + background-color: #fff +} + +.btn-vimeo { + color: #fff; + background-color: #1ab7ea; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-vimeo:focus, .btn-vimeo.focus { + color: #fff; + background-color: #1295bf; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-vimeo:hover { + color: #fff; + background-color: #1295bf; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-vimeo:active, .btn-vimeo.active, .open > .dropdown-toggle.btn-vimeo { + color: #fff; + background-color: #1295bf; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-vimeo:active, .btn-vimeo.active, .open > .dropdown-toggle.btn-vimeo { + background-image: none +} + +.btn-vimeo .badge { + color: #1ab7ea; + background-color: #fff +} + +.btn-vk { + color: #fff; + background-color: #587ea3; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-vk:focus, .btn-vk.focus { + color: #fff; + background-color: #466482; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-vk:hover { + color: #fff; + background-color: #466482; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-vk:active, .btn-vk.active, .open > .dropdown-toggle.btn-vk { + color: #fff; + background-color: #466482; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-vk:active, .btn-vk.active, .open > .dropdown-toggle.btn-vk { + background-image: none +} + +.btn-vk .badge { + color: #587ea3; + background-color: #fff +} + +.btn-yahoo { + color: #fff; + background-color: #720e9e; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-yahoo:focus, .btn-yahoo.focus { + color: #fff; + background-color: #500a6f; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-yahoo:hover { + color: #fff; + background-color: #500a6f; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-yahoo:active, .btn-yahoo.active, .open > .dropdown-toggle.btn-yahoo { + color: #fff; + background-color: #500a6f; + border-color: rgba(0, 0, 0, 0.2) +} + +.btn-yahoo:active, .btn-yahoo.active, .open > .dropdown-toggle.btn-yahoo { + background-image: none +} + +.btn-yahoo .badge { + color: #720e9e; + background-color: #fff +} + +.fc-button { + background: #f4f4f4; + background-image: none; + color: #444; + border-color: #ddd; + border-bottom-color: #ddd +} + +.fc-button:hover, .fc-button:active, .fc-button.hover { + background-color: #e9e9e9 +} + +.fc-header-title h2 { + font-size: 15px; + line-height: 1.6em; + color: #666; + margin-left: 10px +} + +.fc-header-right { + padding-right: 10px +} + +.fc-header-left { + padding-left: 10px +} + +.fc-widget-header { + background: #fafafa +} + +.fc-grid { + width: 100%; + border: 0 +} + +.fc-widget-header:first-of-type, .fc-widget-content:first-of-type { + border-left: 0; + border-right: 0 +} + +.fc-widget-header:last-of-type, .fc-widget-content:last-of-type { + border-right: 0 +} + +.fc-toolbar { + padding: 10px; + margin: 0 +} + +.fc-day-number { + font-size: 20px; + font-weight: 300; + padding-right: 10px +} + +.fc-color-picker { + list-style: none; + margin: 0; + padding: 0 +} + +.fc-color-picker > li { + float: left; + font-size: 30px; + margin-right: 5px; + line-height: 30px +} + +.fc-color-picker > li .fa { + -webkit-transition: -webkit-transform linear .3s; + -moz-transition: -moz-transform linear .3s; + -o-transition: -o-transform linear .3s; + transition: transform linear .3s +} + +.fc-color-picker > li .fa:hover { + -webkit-transform: rotate(30deg); + -ms-transform: rotate(30deg); + -o-transform: rotate(30deg); + transform: rotate(30deg) +} + +#add-new-event { + -webkit-transition: all linear .3s; + -o-transition: all linear .3s; + transition: all linear .3s +} + +.external-event { + padding: 5px 10px; + font-weight: bold; + margin-bottom: 4px; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); + text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); + border-radius: 3px; + cursor: move +} + +.external-event:hover { + box-shadow: inset 0 0 90px rgba(0, 0, 0, 0.2) +} + +.select2-container--default.select2-container--focus, .select2-selection.select2-container--focus, .select2-container--default:focus, .select2-selection:focus, .select2-container--default:active, .select2-selection:active { + outline: none +} + +.select2-container--default .select2-selection--single, .select2-selection .select2-selection--single { + border: 1px solid #d2d6de; + border-radius: 0; + padding: 6px 12px; + height: 34px +} + +.select2-container--default.select2-container--open { + border-color: #3c8dbc +} + +.select2-dropdown { + border: 1px solid #d2d6de; + border-radius: 0 +} + +.select2-container--default .select2-results__option--highlighted[aria-selected] { + background-color: #3c8dbc; + color: white +} + +.select2-results__option { + padding: 6px 12px; + user-select: none; + -webkit-user-select: none +} + +.select2-container .select2-selection--single .select2-selection__rendered { + padding-left: 0; + padding-right: 0; + height: auto; + margin-top: -4px +} + +.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered { + padding-right: 6px; + padding-left: 20px +} + +.select2-container--default .select2-selection--single .select2-selection__arrow { + height: 28px; + right: 3px +} + +.select2-container--default .select2-selection--single .select2-selection__arrow b { + margin-top: 0 +} + +.select2-dropdown .select2-search__field, .select2-search--inline .select2-search__field { + border: 1px solid #d2d6de +} + +.select2-dropdown .select2-search__field:focus, .select2-search--inline .select2-search__field:focus { + outline: none; + border: 1px solid #3c8dbc +} + +.select2-container--default .select2-results__option[aria-disabled=true] { + color: #999 +} + +.select2-container--default .select2-results__option[aria-selected=true] { + background-color: #ddd +} + +.select2-container--default .select2-results__option[aria-selected=true], .select2-container--default .select2-results__option[aria-selected=true]:hover { + color: #444 +} + +.select2-container--default .select2-selection--multiple { + border: 1px solid #d2d6de; + border-radius: 0 +} + +.select2-container--default .select2-selection--multiple:focus { + border-color: #3c8dbc +} + +.select2-container--default.select2-container--focus .select2-selection--multiple { + border-color: #d2d6de +} + +.select2-container--default .select2-selection--multiple .select2-selection__choice { + background-color: #3c8dbc; + border-color: #367fa9; + padding: 1px 10px; + color: #fff +} + +.select2-container--default .select2-selection--multiple .select2-selection__choice__remove { + margin-right: 5px; + color: rgba(255, 255, 255, 0.7) +} + +.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover { + color: #fff +} + +.select2-container .select2-selection--single .select2-selection__rendered { + padding-right: 10px +} + +.pad { + padding: 10px +} + +.margin { + margin: 10px +} + +.margin-bottom { + margin-bottom: 20px +} + +.margin-bottom-none { + margin-bottom: 0 +} + +.margin-r-5 { + margin-right: 5px +} + +.inline { + display: inline +} + +.description-block { + display: block; + margin: 10px 0; + text-align: center +} + +.description-block.margin-bottom { + margin-bottom: 25px +} + +.description-block > .description-header { + margin: 0; + padding: 0; + font-weight: 600; + font-size: 16px +} + +.description-block > .description-text { + text-transform: uppercase +} + +.bg-red, .bg-yellow, .bg-aqua, .bg-blue, .bg-light-blue, .bg-green, .bg-navy, .bg-teal, .bg-olive, .bg-lime, .bg-orange, .bg-fuchsia, .bg-purple, .bg-maroon, .bg-black, .bg-red-active, .bg-yellow-active, .bg-aqua-active, .bg-blue-active, .bg-light-blue-active, .bg-green-active, .bg-navy-active, .bg-teal-active, .bg-olive-active, .bg-lime-active, .bg-orange-active, .bg-fuchsia-active, .bg-purple-active, .bg-maroon-active, .bg-black-active, .callout.callout-danger, .callout.callout-warning, .callout.callout-info, .callout.callout-success, .alert-success, .alert-danger, .alert-error, .alert-warning, .alert-info, .label-danger, .label-info, .label-warning, .label-primary, .label-success, .modal-primary .modal-body, .modal-primary .modal-header, .modal-primary .modal-footer, .modal-warning .modal-body, .modal-warning .modal-header, .modal-warning .modal-footer, .modal-info .modal-body, .modal-info .modal-header, .modal-info .modal-footer, .modal-success .modal-body, .modal-success .modal-header, .modal-success .modal-footer, .modal-danger .modal-body, .modal-danger .modal-header, .modal-danger .modal-footer { + color: #fff !important +} + +.bg-gray { + color: #000; + background-color: #d2d6de !important +} + +.bg-gray-light { + background-color: #f7f7f7 +} + +.bg-black { + background-color: #111 !important +} + +.bg-red, .callout.callout-danger, .alert-danger, .alert-error, .label-danger, .modal-danger .modal-body { + background-color: #dd4b39 !important +} + +.bg-yellow, .callout.callout-warning, .alert-warning, .label-warning, .modal-warning .modal-body { + background-color: #f39c12 !important +} + +.bg-aqua, .callout.callout-info, .alert-info, .label-info, .modal-info .modal-body { + background-color: #00c0ef !important +} + +.bg-blue { + background-color: #0073b7 !important +} + +.bg-light-blue, .label-primary, .modal-primary .modal-body { + background-color: #3c8dbc !important +} + +.bg-green, .callout.callout-success, .alert-success, .label-success, .modal-success .modal-body { + background-color: #00a65a !important +} + +.bg-navy { + background-color: #001f3f !important +} + +.bg-teal { + background-color: #39cccc !important +} + +.bg-olive { + background-color: #3d9970 !important +} + +.bg-lime { + background-color: #01ff70 !important +} + +.bg-orange { + background-color: #ff851b !important +} + +.bg-fuchsia { + background-color: #f012be !important +} + +.bg-purple { + background-color: #605ca8 !important +} + +.bg-maroon { + background-color: #d81b60 !important +} + +.bg-gray-active { + color: #000; + background-color: #b5bbc8 !important +} + +.bg-black-active { + background-color: #000 !important +} + +.bg-red-active, .modal-danger .modal-header, .modal-danger .modal-footer { + background-color: #d33724 !important +} + +.bg-yellow-active, .modal-warning .modal-header, .modal-warning .modal-footer { + background-color: #db8b0b !important +} + +.bg-aqua-active, .modal-info .modal-header, .modal-info .modal-footer { + background-color: #00a7d0 !important +} + +.bg-blue-active { + background-color: #005384 !important +} + +.bg-light-blue-active, .modal-primary .modal-header, .modal-primary .modal-footer { + background-color: #357ca5 !important +} + +.bg-green-active, .modal-success .modal-header, .modal-success .modal-footer { + background-color: #008d4c !important +} + +.bg-navy-active { + background-color: #001a35 !important +} + +.bg-teal-active { + background-color: #30bbbb !important +} + +.bg-olive-active { + background-color: #368763 !important +} + +.bg-lime-active { + background-color: #00e765 !important +} + +.bg-orange-active { + background-color: #ff7701 !important +} + +.bg-fuchsia-active { + background-color: #db0ead !important +} + +.bg-purple-active { + background-color: #555299 !important +} + +.bg-maroon-active { + background-color: #ca195a !important +} + +[class^="bg-"].disabled { + opacity: .65; + filter: alpha(opacity=65) +} + +.text-red { + color: #dd4b39 !important +} + +.text-yellow { + color: #f39c12 !important +} + +.text-aqua { + color: #00c0ef !important +} + +.text-blue { + color: #0073b7 !important +} + +.text-black { + color: #111 !important +} + +.text-light-blue { + color: #3c8dbc !important +} + +.text-green { + color: #00a65a !important +} + +.text-gray { + color: #d2d6de !important +} + +.text-navy { + color: #001f3f !important +} + +.text-teal { + color: #39cccc !important +} + +.text-olive { + color: #3d9970 !important +} + +.text-lime { + color: #01ff70 !important +} + +.text-orange { + color: #ff851b !important +} + +.text-fuchsia { + color: #f012be !important +} + +.text-purple { + color: #605ca8 !important +} + +.text-maroon { + color: #d81b60 !important +} + +.link-muted { + color: #7a869d +} + +.link-muted:hover, .link-muted:focus { + color: #606c84 +} + +.link-black { + color: #666 +} + +.link-black:hover, .link-black:focus { + color: #999 +} + +.hide { + display: none !important +} + +.no-border { + border: 0 !important +} + +.no-padding { + padding: 0 !important +} + +.no-margin { + margin: 0 !important +} + +.no-shadow { + box-shadow: none !important +} + +.list-unstyled, .chart-legend, .contacts-list, .users-list, .mailbox-attachments { + list-style: none; + margin: 0; + padding: 0 +} + +.list-group-unbordered > .list-group-item { + border-left: 0; + border-right: 0; + border-radius: 0; + padding-left: 0; + padding-right: 0 +} + +.flat { + border-radius: 0 !important +} + +.text-bold, .text-bold.table td, .text-bold.table th { + font-weight: 700 +} + +.text-sm { + font-size: 12px +} + +.jqstooltip { + padding: 5px !important; + width: auto !important; + height: auto !important +} + +.bg-teal-gradient { + background: #39cccc !important; + background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #39cccc), color-stop(1, #7adddd)) !important; + background: -ms-linear-gradient(bottom, #39cccc, #7adddd) !important; + background: -moz-linear-gradient(center bottom, #39cccc 0, #7adddd 100%) !important; + background: -o-linear-gradient(#7adddd, #39cccc) !important; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#7adddd', endColorstr='#39cccc', GradientType=0) !important; + color: #fff +} + +.bg-light-blue-gradient { + background: #3c8dbc !important; + background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #3c8dbc), color-stop(1, #67a8ce)) !important; + background: -ms-linear-gradient(bottom, #3c8dbc, #67a8ce) !important; + background: -moz-linear-gradient(center bottom, #3c8dbc 0, #67a8ce 100%) !important; + background: -o-linear-gradient(#67a8ce, #3c8dbc) !important; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#67a8ce', endColorstr='#3c8dbc', GradientType=0) !important; + color: #fff +} + +.bg-blue-gradient { + background: #0073b7 !important; + background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #0073b7), color-stop(1, #0089db)) !important; + background: -ms-linear-gradient(bottom, #0073b7, #0089db) !important; + background: -moz-linear-gradient(center bottom, #0073b7 0, #0089db 100%) !important; + background: -o-linear-gradient(#0089db, #0073b7) !important; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0089db', endColorstr='#0073b7', GradientType=0) !important; + color: #fff +} + +.bg-aqua-gradient { + background: #00c0ef !important; + background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #00c0ef), color-stop(1, #14d1ff)) !important; + background: -ms-linear-gradient(bottom, #00c0ef, #14d1ff) !important; + background: -moz-linear-gradient(center bottom, #00c0ef 0, #14d1ff 100%) !important; + background: -o-linear-gradient(#14d1ff, #00c0ef) !important; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#14d1ff', endColorstr='#00c0ef', GradientType=0) !important; + color: #fff +} + +.bg-yellow-gradient { + background: #f39c12 !important; + background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #f39c12), color-stop(1, #f7bc60)) !important; + background: -ms-linear-gradient(bottom, #f39c12, #f7bc60) !important; + background: -moz-linear-gradient(center bottom, #f39c12 0, #f7bc60 100%) !important; + background: -o-linear-gradient(#f7bc60, #f39c12) !important; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f7bc60', endColorstr='#f39c12', GradientType=0) !important; + color: #fff +} + +.bg-purple-gradient { + background: #605ca8 !important; + background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #605ca8), color-stop(1, #9491c4)) !important; + background: -ms-linear-gradient(bottom, #605ca8, #9491c4) !important; + background: -moz-linear-gradient(center bottom, #605ca8 0, #9491c4 100%) !important; + background: -o-linear-gradient(#9491c4, #605ca8) !important; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#9491c4', endColorstr='#605ca8', GradientType=0) !important; + color: #fff +} + +.bg-green-gradient { + background: #00a65a !important; + background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #00a65a), color-stop(1, #00ca6d)) !important; + background: -ms-linear-gradient(bottom, #00a65a, #00ca6d) !important; + background: -moz-linear-gradient(center bottom, #00a65a 0, #00ca6d 100%) !important; + background: -o-linear-gradient(#00ca6d, #00a65a) !important; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ca6d', endColorstr='#00a65a', GradientType=0) !important; + color: #fff +} + +.bg-red-gradient { + background: #dd4b39 !important; + background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #dd4b39), color-stop(1, #e47365)) !important; + background: -ms-linear-gradient(bottom, #dd4b39, #e47365) !important; + background: -moz-linear-gradient(center bottom, #dd4b39 0, #e47365 100%) !important; + background: -o-linear-gradient(#e47365, #dd4b39) !important; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#e47365', endColorstr='#dd4b39', GradientType=0) !important; + color: #fff +} + +.bg-black-gradient { + background: #111 !important; + background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #111), color-stop(1, #2b2b2b)) !important; + background: -ms-linear-gradient(bottom, #111, #2b2b2b) !important; + background: -moz-linear-gradient(center bottom, #111 0, #2b2b2b 100%) !important; + background: -o-linear-gradient(#2b2b2b, #111) !important; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#2b2b2b', endColorstr='#111111', GradientType=0) !important; + color: #fff +} + +.bg-maroon-gradient { + background: #d81b60 !important; + background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #d81b60), color-stop(1, #e73f7c)) !important; + background: -ms-linear-gradient(bottom, #d81b60, #e73f7c) !important; + background: -moz-linear-gradient(center bottom, #d81b60 0, #e73f7c 100%) !important; + background: -o-linear-gradient(#e73f7c, #d81b60) !important; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#e73f7c', endColorstr='#d81b60', GradientType=0) !important; + color: #fff +} + +.description-block .description-icon { + font-size: 16px +} + +.no-pad-top { + padding-top: 0 +} + +.position-static { + position: static !important +} + +.list-header { + font-size: 15px; + padding: 10px 4px; + font-weight: bold; + color: #666 +} + +.list-seperator { + height: 1px; + background: #f4f4f4; + margin: 15px 0 9px 0 +} + +.list-link > a { + padding: 4px; + color: #777 +} + +.list-link > a:hover { + color: #222 +} + +.font-light { + font-weight: 300 +} + +.user-block:before, .user-block:after { + content: " "; + display: table +} + +.user-block:after { + clear: both +} + +.user-block img { + width: 40px; + height: 40px; + float: left +} + +.user-block .username, .user-block .description, .user-block .comment { + display: block; + margin-left: 50px +} + +.user-block .username { + font-size: 16px; + font-weight: 600 +} + +.user-block .description { + color: #999; + font-size: 13px +} + +.user-block.user-block-sm .username, .user-block.user-block-sm .description, .user-block.user-block-sm .comment { + margin-left: 40px +} + +.user-block.user-block-sm .username { + font-size: 14px +} + +.img-sm, .img-md, .img-lg, .box-comments .box-comment img, .user-block.user-block-sm img { + float: left +} + +.img-sm, .box-comments .box-comment img, .user-block.user-block-sm img { + width: 30px !important; + height: 30px !important +} + +.img-sm + .img-push { + margin-left: 40px +} + +.img-md { + width: 60px; + height: 60px +} + +.img-md + .img-push { + margin-left: 70px +} + +.img-lg { + width: 100px; + height: 100px +} + +.img-lg + .img-push { + margin-left: 110px +} + +.img-bordered { + border: 3px solid #d2d6de; + padding: 3px +} + +.img-bordered-sm { + border: 2px solid #d2d6de; + padding: 2px +} + +.attachment-block { + border: 1px solid #f4f4f4; + padding: 5px; + margin-bottom: 10px; + background: #f7f7f7 +} + +.attachment-block .attachment-img { + max-width: 100px; + max-height: 100px; + height: auto; + float: left +} + +.attachment-block .attachment-pushed { + margin-left: 110px +} + +.attachment-block .attachment-heading { + margin: 0 +} + +.attachment-block .attachment-text { + color: #555 +} + +.connectedSortable { + min-height: 100px +} + +.ui-helper-hidden-accessible { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px +} + +.sort-highlight { + background: #f4f4f4; + border: 1px dashed #ddd; + margin-bottom: 10px +} + +.full-opacity-hover { + opacity: .65; + filter: alpha(opacity=65) +} + +.full-opacity-hover:hover { + opacity: 1; + filter: alpha(opacity=100) +} + +.chart { + position: relative; + overflow: hidden; + width: 100% +} + +.chart svg, .chart canvas { + width: 100% !important +} + +@media print { + .no-print, .main-sidebar, .left-side, .main-header, .content-header { + display: none !important + } + + .content-wrapper, .right-side, .main-footer { + margin-left: 0 !important; + min-height: 0 !important; + -webkit-transform: translate(0, 0) !important; + -ms-transform: translate(0, 0) !important; + -o-transform: translate(0, 0) !important; + transform: translate(0, 0) !important + } + + .fixed .content-wrapper, .fixed .right-side { + padding-top: 0 !important + } + + .invoice { + width: 100%; + border: 0; + margin: 0; + padding: 0 + } + + .invoice-col { + float: left; + width: 33.3333333% + } + + .table-responsive { + overflow: auto + } + + .table-responsive > .table tr th, .table-responsive > .table tr td { + white-space: normal !important + } +} \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/css/all-skins.min.css b/spring-boot-22-FarstPlus/src/main/resources/templates/static/css/all-skins.min.css new file mode 100644 index 0000000..e1d2398 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/css/all-skins.min.css @@ -0,0 +1 @@ +.skin-blue .main-header .navbar{background-color:#3c8dbc}.skin-blue .main-header .navbar .nav>li>a{color:#fff}.skin-blue .main-header .navbar .nav>li>a:hover,.skin-blue .main-header .navbar .nav>li>a:active,.skin-blue .main-header .navbar .nav>li>a:focus,.skin-blue .main-header .navbar .nav .open>a,.skin-blue .main-header .navbar .nav .open>a:hover,.skin-blue .main-header .navbar .nav .open>a:focus,.skin-blue .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-blue .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-blue .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue .main-header .navbar .sidebar-toggle:hover{background-color:#367fa9}@media (max-width:767px){.skin-blue .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-blue .main-header .navbar .dropdown-menu li a{color:#fff}.skin-blue .main-header .navbar .dropdown-menu li a:hover{background:#367fa9}}.skin-blue .main-header .logo{background-color:#367fa9;color:#fff;border-bottom:0 solid transparent}.skin-blue .main-header .logo:hover{background-color:#357ca5}.skin-blue .main-header li.user-header{background-color:#3c8dbc}.skin-blue .content-header{background:transparent}.skin-blue .wrapper,.skin-blue .main-sidebar,.skin-blue .left-side{background-color:#222d32}.skin-blue .user-panel>.info,.skin-blue .user-panel>.info>a{color:#fff}.skin-blue .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-blue .sidebar-menu>li>a{border-left:3px solid transparent}.skin-blue .sidebar-menu>li:hover>a,.skin-blue .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#3c8dbc}.skin-blue .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-blue .sidebar a{color:#b8c7ce}.skin-blue .sidebar a:hover{text-decoration:none}.skin-blue .treeview-menu>li>a{color:#8aa4af}.skin-blue .treeview-menu>li.active>a,.skin-blue .treeview-menu>li>a:hover{color:#fff}.skin-blue .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-blue .sidebar-form input[type="text"],.skin-blue .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px}.skin-blue .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-blue .sidebar-form input[type="text"]:focus,.skin-blue .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-blue .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-blue .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-blue.layout-top-nav .main-header>.logo{background-color:#3c8dbc;color:#fff;border-bottom:0 solid transparent}.skin-blue.layout-top-nav .main-header>.logo:hover{background-color:#3b8ab8}.skin-blue-light .main-header .navbar{background-color:#3c8dbc}.skin-blue-light .main-header .navbar .nav>li>a{color:#fff}.skin-blue-light .main-header .navbar .nav>li>a:hover,.skin-blue-light .main-header .navbar .nav>li>a:active,.skin-blue-light .main-header .navbar .nav>li>a:focus,.skin-blue-light .main-header .navbar .nav .open>a,.skin-blue-light .main-header .navbar .nav .open>a:hover,.skin-blue-light .main-header .navbar .nav .open>a:focus,.skin-blue-light .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-blue-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue-light .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-blue-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue-light .main-header .navbar .sidebar-toggle:hover{background-color:#367fa9}@media (max-width:767px){.skin-blue-light .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-blue-light .main-header .navbar .dropdown-menu li a{color:#fff}.skin-blue-light .main-header .navbar .dropdown-menu li a:hover{background:#367fa9}}.skin-blue-light .main-header .logo{background-color:#3c8dbc;color:#fff;border-bottom:0 solid transparent}.skin-blue-light .main-header .logo:hover{background-color:#3b8ab8}.skin-blue-light .main-header li.user-header{background-color:#3c8dbc}.skin-blue-light .content-header{background:transparent}.skin-blue-light .wrapper,.skin-blue-light .main-sidebar,.skin-blue-light .left-side{background-color:#f9fafc}.skin-blue-light .content-wrapper,.skin-blue-light .main-footer{border-left:1px solid #d2d6de}.skin-blue-light .user-panel>.info,.skin-blue-light .user-panel>.info>a{color:#444}.skin-blue-light .sidebar-menu>li{-webkit-transition:border-left-color .3s ease;-o-transition:border-left-color .3s ease;transition:border-left-color .3s ease}.skin-blue-light .sidebar-menu>li.header{color:#848484;background:#f9fafc}.skin-blue-light .sidebar-menu>li>a{border-left:3px solid transparent;font-weight:600}.skin-blue-light .sidebar-menu>li:hover>a,.skin-blue-light .sidebar-menu>li.active>a{color:#000;background:#f4f4f5}.skin-blue-light .sidebar-menu>li.active{border-left-color:#3c8dbc}.skin-blue-light .sidebar-menu>li.active>a{font-weight:600}.skin-blue-light .sidebar-menu>li>.treeview-menu{background:#f4f4f5}.skin-blue-light .sidebar a{color:#444}.skin-blue-light .sidebar a:hover{text-decoration:none}.skin-blue-light .treeview-menu>li>a{color:#777}.skin-blue-light .treeview-menu>li.active>a,.skin-blue-light .treeview-menu>li>a:hover{color:#000}.skin-blue-light .treeview-menu>li.active>a{font-weight:600}.skin-blue-light .sidebar-form{border-radius:3px;border:1px solid #d2d6de;margin:10px 10px}.skin-blue-light .sidebar-form input[type="text"],.skin-blue-light .sidebar-form .btn{box-shadow:none;background-color:#fff;border:1px solid transparent;height:35px}.skin-blue-light .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-blue-light .sidebar-form input[type="text"]:focus,.skin-blue-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-blue-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-blue-light .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}@media (min-width:768px){.skin-blue-light.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{border-left:1px solid #d2d6de}}.skin-blue-light .main-footer{border-top-color:#d2d6de}.skin-blue.layout-top-nav .main-header>.logo{background-color:#3c8dbc;color:#fff;border-bottom:0 solid transparent}.skin-blue.layout-top-nav .main-header>.logo:hover{background-color:#3b8ab8}.skin-black .main-header{-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.skin-black .main-header .navbar-toggle{color:#333}.skin-black .main-header .navbar-brand{color:#333;border-right:1px solid #eee}.skin-black .main-header .navbar{background-color:#fff}.skin-black .main-header .navbar .nav>li>a{color:#333}.skin-black .main-header .navbar .nav>li>a:hover,.skin-black .main-header .navbar .nav>li>a:active,.skin-black .main-header .navbar .nav>li>a:focus,.skin-black .main-header .navbar .nav .open>a,.skin-black .main-header .navbar .nav .open>a:hover,.skin-black .main-header .navbar .nav .open>a:focus,.skin-black .main-header .navbar .nav>.active>a{background:#fff;color:#999}.skin-black .main-header .navbar .sidebar-toggle{color:#333}.skin-black .main-header .navbar .sidebar-toggle:hover{color:#999;background:#fff}.skin-black .main-header .navbar>.sidebar-toggle{color:#333;border-right:1px solid #eee}.skin-black .main-header .navbar .navbar-nav>li>a{border-right:1px solid #eee}.skin-black .main-header .navbar .navbar-custom-menu .navbar-nav>li>a,.skin-black .main-header .navbar .navbar-right>li>a{border-left:1px solid #eee;border-right-width:0}.skin-black .main-header>.logo{background-color:#fff;color:#333;border-bottom:0 solid transparent;border-right:1px solid #eee}.skin-black .main-header>.logo:hover{background-color:#fcfcfc}@media (max-width:767px){.skin-black .main-header>.logo{background-color:#222;color:#fff;border-bottom:0 solid transparent;border-right:none}.skin-black .main-header>.logo:hover{background-color:#1f1f1f}}.skin-black .main-header li.user-header{background-color:#222}.skin-black .content-header{background:transparent;box-shadow:none}.skin-black .wrapper,.skin-black .main-sidebar,.skin-black .left-side{background-color:#222d32}.skin-black .user-panel>.info,.skin-black .user-panel>.info>a{color:#fff}.skin-black .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-black .sidebar-menu>li>a{border-left:3px solid transparent}.skin-black .sidebar-menu>li:hover>a,.skin-black .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#fff}.skin-black .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-black .sidebar a{color:#b8c7ce}.skin-black .sidebar a:hover{text-decoration:none}.skin-black .treeview-menu>li>a{color:#8aa4af}.skin-black .treeview-menu>li.active>a,.skin-black .treeview-menu>li>a:hover{color:#fff}.skin-black .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-black .sidebar-form input[type="text"],.skin-black .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px}.skin-black .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-black .sidebar-form input[type="text"]:focus,.skin-black .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-black .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-black .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-black .pace .pace-progress{background:#222}.skin-black .pace .pace-activity{border-top-color:#222;border-left-color:#222}.skin-black-light .main-header{-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.skin-black-light .main-header .navbar-toggle{color:#333}.skin-black-light .main-header .navbar-brand{color:#333;border-right:1px solid #eee}.skin-black-light .main-header .navbar{background-color:#fff}.skin-black-light .main-header .navbar .nav>li>a{color:#333}.skin-black-light .main-header .navbar .nav>li>a:hover,.skin-black-light .main-header .navbar .nav>li>a:active,.skin-black-light .main-header .navbar .nav>li>a:focus,.skin-black-light .main-header .navbar .nav .open>a,.skin-black-light .main-header .navbar .nav .open>a:hover,.skin-black-light .main-header .navbar .nav .open>a:focus,.skin-black-light .main-header .navbar .nav>.active>a{background:#fff;color:#999}.skin-black-light .main-header .navbar .sidebar-toggle{color:#333}.skin-black-light .main-header .navbar .sidebar-toggle:hover{color:#999;background:#fff}.skin-black-light .main-header .navbar>.sidebar-toggle{color:#333;border-right:1px solid #eee}.skin-black-light .main-header .navbar .navbar-nav>li>a{border-right:1px solid #eee}.skin-black-light .main-header .navbar .navbar-custom-menu .navbar-nav>li>a,.skin-black-light .main-header .navbar .navbar-right>li>a{border-left:1px solid #eee;border-right-width:0}.skin-black-light .main-header>.logo{background-color:#fff;color:#333;border-bottom:0 solid transparent;border-right:1px solid #eee}.skin-black-light .main-header>.logo:hover{background-color:#fcfcfc}@media (max-width:767px){.skin-black-light .main-header>.logo{background-color:#222;color:#fff;border-bottom:0 solid transparent;border-right:none}.skin-black-light .main-header>.logo:hover{background-color:#1f1f1f}}.skin-black-light .main-header li.user-header{background-color:#222}.skin-black-light .content-header{background:transparent;box-shadow:none}.skin-black-light .wrapper,.skin-black-light .main-sidebar,.skin-black-light .left-side{background-color:#f9fafc}.skin-black-light .content-wrapper,.skin-black-light .main-footer{border-left:1px solid #d2d6de}.skin-black-light .user-panel>.info,.skin-black-light .user-panel>.info>a{color:#444}.skin-black-light .sidebar-menu>li{-webkit-transition:border-left-color .3s ease;-o-transition:border-left-color .3s ease;transition:border-left-color .3s ease}.skin-black-light .sidebar-menu>li.header{color:#848484;background:#f9fafc}.skin-black-light .sidebar-menu>li>a{border-left:3px solid transparent;font-weight:600}.skin-black-light .sidebar-menu>li:hover>a,.skin-black-light .sidebar-menu>li.active>a{color:#000;background:#f4f4f5}.skin-black-light .sidebar-menu>li.active{border-left-color:#fff}.skin-black-light .sidebar-menu>li.active>a{font-weight:600}.skin-black-light .sidebar-menu>li>.treeview-menu{background:#f4f4f5}.skin-black-light .sidebar a{color:#444}.skin-black-light .sidebar a:hover{text-decoration:none}.skin-black-light .treeview-menu>li>a{color:#777}.skin-black-light .treeview-menu>li.active>a,.skin-black-light .treeview-menu>li>a:hover{color:#000}.skin-black-light .treeview-menu>li.active>a{font-weight:600}.skin-black-light .sidebar-form{border-radius:3px;border:1px solid #d2d6de;margin:10px 10px}.skin-black-light .sidebar-form input[type="text"],.skin-black-light .sidebar-form .btn{box-shadow:none;background-color:#fff;border:1px solid transparent;height:35px}.skin-black-light .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-black-light .sidebar-form input[type="text"]:focus,.skin-black-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-black-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-black-light .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}@media (min-width:768px){.skin-black-light.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{border-left:1px solid #d2d6de}}.skin-green .main-header .navbar{background-color:#00a65a}.skin-green .main-header .navbar .nav>li>a{color:#fff}.skin-green .main-header .navbar .nav>li>a:hover,.skin-green .main-header .navbar .nav>li>a:active,.skin-green .main-header .navbar .nav>li>a:focus,.skin-green .main-header .navbar .nav .open>a,.skin-green .main-header .navbar .nav .open>a:hover,.skin-green .main-header .navbar .nav .open>a:focus,.skin-green .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-green .main-header .navbar .sidebar-toggle{color:#fff}.skin-green .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-green .main-header .navbar .sidebar-toggle{color:#fff}.skin-green .main-header .navbar .sidebar-toggle:hover{background-color:#008d4c}@media (max-width:767px){.skin-green .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-green .main-header .navbar .dropdown-menu li a{color:#fff}.skin-green .main-header .navbar .dropdown-menu li a:hover{background:#008d4c}}.skin-green .main-header .logo{background-color:#008d4c;color:#fff;border-bottom:0 solid transparent}.skin-green .main-header .logo:hover{background-color:#008749}.skin-green .main-header li.user-header{background-color:#00a65a}.skin-green .content-header{background:transparent}.skin-green .wrapper,.skin-green .main-sidebar,.skin-green .left-side{background-color:#222d32}.skin-green .user-panel>.info,.skin-green .user-panel>.info>a{color:#fff}.skin-green .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-green .sidebar-menu>li>a{border-left:3px solid transparent}.skin-green .sidebar-menu>li:hover>a,.skin-green .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#00a65a}.skin-green .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-green .sidebar a{color:#b8c7ce}.skin-green .sidebar a:hover{text-decoration:none}.skin-green .treeview-menu>li>a{color:#8aa4af}.skin-green .treeview-menu>li.active>a,.skin-green .treeview-menu>li>a:hover{color:#fff}.skin-green .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-green .sidebar-form input[type="text"],.skin-green .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px}.skin-green .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-green .sidebar-form input[type="text"]:focus,.skin-green .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-green .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-green .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-green-light .main-header .navbar{background-color:#00a65a}.skin-green-light .main-header .navbar .nav>li>a{color:#fff}.skin-green-light .main-header .navbar .nav>li>a:hover,.skin-green-light .main-header .navbar .nav>li>a:active,.skin-green-light .main-header .navbar .nav>li>a:focus,.skin-green-light .main-header .navbar .nav .open>a,.skin-green-light .main-header .navbar .nav .open>a:hover,.skin-green-light .main-header .navbar .nav .open>a:focus,.skin-green-light .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-green-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-green-light .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-green-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-green-light .main-header .navbar .sidebar-toggle:hover{background-color:#008d4c}@media (max-width:767px){.skin-green-light .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-green-light .main-header .navbar .dropdown-menu li a{color:#fff}.skin-green-light .main-header .navbar .dropdown-menu li a:hover{background:#008d4c}}.skin-green-light .main-header .logo{background-color:#00a65a;color:#fff;border-bottom:0 solid transparent}.skin-green-light .main-header .logo:hover{background-color:#00a157}.skin-green-light .main-header li.user-header{background-color:#00a65a}.skin-green-light .content-header{background:transparent}.skin-green-light .wrapper,.skin-green-light .main-sidebar,.skin-green-light .left-side{background-color:#f9fafc}.skin-green-light .content-wrapper,.skin-green-light .main-footer{border-left:1px solid #d2d6de}.skin-green-light .user-panel>.info,.skin-green-light .user-panel>.info>a{color:#444}.skin-green-light .sidebar-menu>li{-webkit-transition:border-left-color .3s ease;-o-transition:border-left-color .3s ease;transition:border-left-color .3s ease}.skin-green-light .sidebar-menu>li.header{color:#848484;background:#f9fafc}.skin-green-light .sidebar-menu>li>a{border-left:3px solid transparent;font-weight:600}.skin-green-light .sidebar-menu>li:hover>a,.skin-green-light .sidebar-menu>li.active>a{color:#000;background:#f4f4f5}.skin-green-light .sidebar-menu>li.active{border-left-color:#00a65a}.skin-green-light .sidebar-menu>li.active>a{font-weight:600}.skin-green-light .sidebar-menu>li>.treeview-menu{background:#f4f4f5}.skin-green-light .sidebar a{color:#444}.skin-green-light .sidebar a:hover{text-decoration:none}.skin-green-light .treeview-menu>li>a{color:#777}.skin-green-light .treeview-menu>li.active>a,.skin-green-light .treeview-menu>li>a:hover{color:#000}.skin-green-light .treeview-menu>li.active>a{font-weight:600}.skin-green-light .sidebar-form{border-radius:3px;border:1px solid #d2d6de;margin:10px 10px}.skin-green-light .sidebar-form input[type="text"],.skin-green-light .sidebar-form .btn{box-shadow:none;background-color:#fff;border:1px solid transparent;height:35px}.skin-green-light .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-green-light .sidebar-form input[type="text"]:focus,.skin-green-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-green-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-green-light .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}@media (min-width:768px){.skin-green-light.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{border-left:1px solid #d2d6de}}.skin-red .main-header .navbar{background-color:#dd4b39}.skin-red .main-header .navbar .nav>li>a{color:#fff}.skin-red .main-header .navbar .nav>li>a:hover,.skin-red .main-header .navbar .nav>li>a:active,.skin-red .main-header .navbar .nav>li>a:focus,.skin-red .main-header .navbar .nav .open>a,.skin-red .main-header .navbar .nav .open>a:hover,.skin-red .main-header .navbar .nav .open>a:focus,.skin-red .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-red .main-header .navbar .sidebar-toggle{color:#fff}.skin-red .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-red .main-header .navbar .sidebar-toggle{color:#fff}.skin-red .main-header .navbar .sidebar-toggle:hover{background-color:#d73925}@media (max-width:767px){.skin-red .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-red .main-header .navbar .dropdown-menu li a{color:#fff}.skin-red .main-header .navbar .dropdown-menu li a:hover{background:#d73925}}.skin-red .main-header .logo{background-color:#d73925;color:#fff;border-bottom:0 solid transparent}.skin-red .main-header .logo:hover{background-color:#d33724}.skin-red .main-header li.user-header{background-color:#dd4b39}.skin-red .content-header{background:transparent}.skin-red .wrapper,.skin-red .main-sidebar,.skin-red .left-side{background-color:#222d32}.skin-red .user-panel>.info,.skin-red .user-panel>.info>a{color:#fff}.skin-red .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-red .sidebar-menu>li>a{border-left:3px solid transparent}.skin-red .sidebar-menu>li:hover>a,.skin-red .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#dd4b39}.skin-red .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-red .sidebar a{color:#b8c7ce}.skin-red .sidebar a:hover{text-decoration:none}.skin-red .treeview-menu>li>a{color:#8aa4af}.skin-red .treeview-menu>li.active>a,.skin-red .treeview-menu>li>a:hover{color:#fff}.skin-red .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-red .sidebar-form input[type="text"],.skin-red .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px}.skin-red .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-red .sidebar-form input[type="text"]:focus,.skin-red .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-red .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-red .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-red-light .main-header .navbar{background-color:#dd4b39}.skin-red-light .main-header .navbar .nav>li>a{color:#fff}.skin-red-light .main-header .navbar .nav>li>a:hover,.skin-red-light .main-header .navbar .nav>li>a:active,.skin-red-light .main-header .navbar .nav>li>a:focus,.skin-red-light .main-header .navbar .nav .open>a,.skin-red-light .main-header .navbar .nav .open>a:hover,.skin-red-light .main-header .navbar .nav .open>a:focus,.skin-red-light .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-red-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-red-light .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-red-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-red-light .main-header .navbar .sidebar-toggle:hover{background-color:#d73925}@media (max-width:767px){.skin-red-light .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-red-light .main-header .navbar .dropdown-menu li a{color:#fff}.skin-red-light .main-header .navbar .dropdown-menu li a:hover{background:#d73925}}.skin-red-light .main-header .logo{background-color:#dd4b39;color:#fff;border-bottom:0 solid transparent}.skin-red-light .main-header .logo:hover{background-color:#dc4735}.skin-red-light .main-header li.user-header{background-color:#dd4b39}.skin-red-light .content-header{background:transparent}.skin-red-light .wrapper,.skin-red-light .main-sidebar,.skin-red-light .left-side{background-color:#f9fafc}.skin-red-light .content-wrapper,.skin-red-light .main-footer{border-left:1px solid #d2d6de}.skin-red-light .user-panel>.info,.skin-red-light .user-panel>.info>a{color:#444}.skin-red-light .sidebar-menu>li{-webkit-transition:border-left-color .3s ease;-o-transition:border-left-color .3s ease;transition:border-left-color .3s ease}.skin-red-light .sidebar-menu>li.header{color:#848484;background:#f9fafc}.skin-red-light .sidebar-menu>li>a{border-left:3px solid transparent;font-weight:600}.skin-red-light .sidebar-menu>li:hover>a,.skin-red-light .sidebar-menu>li.active>a{color:#000;background:#f4f4f5}.skin-red-light .sidebar-menu>li.active{border-left-color:#dd4b39}.skin-red-light .sidebar-menu>li.active>a{font-weight:600}.skin-red-light .sidebar-menu>li>.treeview-menu{background:#f4f4f5}.skin-red-light .sidebar a{color:#444}.skin-red-light .sidebar a:hover{text-decoration:none}.skin-red-light .treeview-menu>li>a{color:#777}.skin-red-light .treeview-menu>li.active>a,.skin-red-light .treeview-menu>li>a:hover{color:#000}.skin-red-light .treeview-menu>li.active>a{font-weight:600}.skin-red-light .sidebar-form{border-radius:3px;border:1px solid #d2d6de;margin:10px 10px}.skin-red-light .sidebar-form input[type="text"],.skin-red-light .sidebar-form .btn{box-shadow:none;background-color:#fff;border:1px solid transparent;height:35px}.skin-red-light .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-red-light .sidebar-form input[type="text"]:focus,.skin-red-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-red-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-red-light .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}@media (min-width:768px){.skin-red-light.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{border-left:1px solid #d2d6de}}.skin-yellow .main-header .navbar{background-color:#f39c12}.skin-yellow .main-header .navbar .nav>li>a{color:#fff}.skin-yellow .main-header .navbar .nav>li>a:hover,.skin-yellow .main-header .navbar .nav>li>a:active,.skin-yellow .main-header .navbar .nav>li>a:focus,.skin-yellow .main-header .navbar .nav .open>a,.skin-yellow .main-header .navbar .nav .open>a:hover,.skin-yellow .main-header .navbar .nav .open>a:focus,.skin-yellow .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-yellow .main-header .navbar .sidebar-toggle{color:#fff}.skin-yellow .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-yellow .main-header .navbar .sidebar-toggle{color:#fff}.skin-yellow .main-header .navbar .sidebar-toggle:hover{background-color:#e08e0b}@media (max-width:767px){.skin-yellow .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-yellow .main-header .navbar .dropdown-menu li a{color:#fff}.skin-yellow .main-header .navbar .dropdown-menu li a:hover{background:#e08e0b}}.skin-yellow .main-header .logo{background-color:#e08e0b;color:#fff;border-bottom:0 solid transparent}.skin-yellow .main-header .logo:hover{background-color:#db8b0b}.skin-yellow .main-header li.user-header{background-color:#f39c12}.skin-yellow .content-header{background:transparent}.skin-yellow .wrapper,.skin-yellow .main-sidebar,.skin-yellow .left-side{background-color:#222d32}.skin-yellow .user-panel>.info,.skin-yellow .user-panel>.info>a{color:#fff}.skin-yellow .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-yellow .sidebar-menu>li>a{border-left:3px solid transparent}.skin-yellow .sidebar-menu>li:hover>a,.skin-yellow .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#f39c12}.skin-yellow .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-yellow .sidebar a{color:#b8c7ce}.skin-yellow .sidebar a:hover{text-decoration:none}.skin-yellow .treeview-menu>li>a{color:#8aa4af}.skin-yellow .treeview-menu>li.active>a,.skin-yellow .treeview-menu>li>a:hover{color:#fff}.skin-yellow .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-yellow .sidebar-form input[type="text"],.skin-yellow .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px}.skin-yellow .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-yellow .sidebar-form input[type="text"]:focus,.skin-yellow .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-yellow .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-yellow .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-yellow-light .main-header .navbar{background-color:#f39c12}.skin-yellow-light .main-header .navbar .nav>li>a{color:#fff}.skin-yellow-light .main-header .navbar .nav>li>a:hover,.skin-yellow-light .main-header .navbar .nav>li>a:active,.skin-yellow-light .main-header .navbar .nav>li>a:focus,.skin-yellow-light .main-header .navbar .nav .open>a,.skin-yellow-light .main-header .navbar .nav .open>a:hover,.skin-yellow-light .main-header .navbar .nav .open>a:focus,.skin-yellow-light .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-yellow-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-yellow-light .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-yellow-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-yellow-light .main-header .navbar .sidebar-toggle:hover{background-color:#e08e0b}@media (max-width:767px){.skin-yellow-light .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-yellow-light .main-header .navbar .dropdown-menu li a{color:#fff}.skin-yellow-light .main-header .navbar .dropdown-menu li a:hover{background:#e08e0b}}.skin-yellow-light .main-header .logo{background-color:#f39c12;color:#fff;border-bottom:0 solid transparent}.skin-yellow-light .main-header .logo:hover{background-color:#f39a0d}.skin-yellow-light .main-header li.user-header{background-color:#f39c12}.skin-yellow-light .content-header{background:transparent}.skin-yellow-light .wrapper,.skin-yellow-light .main-sidebar,.skin-yellow-light .left-side{background-color:#f9fafc}.skin-yellow-light .content-wrapper,.skin-yellow-light .main-footer{border-left:1px solid #d2d6de}.skin-yellow-light .user-panel>.info,.skin-yellow-light .user-panel>.info>a{color:#444}.skin-yellow-light .sidebar-menu>li{-webkit-transition:border-left-color .3s ease;-o-transition:border-left-color .3s ease;transition:border-left-color .3s ease}.skin-yellow-light .sidebar-menu>li.header{color:#848484;background:#f9fafc}.skin-yellow-light .sidebar-menu>li>a{border-left:3px solid transparent;font-weight:600}.skin-yellow-light .sidebar-menu>li:hover>a,.skin-yellow-light .sidebar-menu>li.active>a{color:#000;background:#f4f4f5}.skin-yellow-light .sidebar-menu>li.active{border-left-color:#f39c12}.skin-yellow-light .sidebar-menu>li.active>a{font-weight:600}.skin-yellow-light .sidebar-menu>li>.treeview-menu{background:#f4f4f5}.skin-yellow-light .sidebar a{color:#444}.skin-yellow-light .sidebar a:hover{text-decoration:none}.skin-yellow-light .treeview-menu>li>a{color:#777}.skin-yellow-light .treeview-menu>li.active>a,.skin-yellow-light .treeview-menu>li>a:hover{color:#000}.skin-yellow-light .treeview-menu>li.active>a{font-weight:600}.skin-yellow-light .sidebar-form{border-radius:3px;border:1px solid #d2d6de;margin:10px 10px}.skin-yellow-light .sidebar-form input[type="text"],.skin-yellow-light .sidebar-form .btn{box-shadow:none;background-color:#fff;border:1px solid transparent;height:35px}.skin-yellow-light .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-yellow-light .sidebar-form input[type="text"]:focus,.skin-yellow-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-yellow-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-yellow-light .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}@media (min-width:768px){.skin-yellow-light.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{border-left:1px solid #d2d6de}}.skin-purple .main-header .navbar{background-color:#605ca8}.skin-purple .main-header .navbar .nav>li>a{color:#fff}.skin-purple .main-header .navbar .nav>li>a:hover,.skin-purple .main-header .navbar .nav>li>a:active,.skin-purple .main-header .navbar .nav>li>a:focus,.skin-purple .main-header .navbar .nav .open>a,.skin-purple .main-header .navbar .nav .open>a:hover,.skin-purple .main-header .navbar .nav .open>a:focus,.skin-purple .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-purple .main-header .navbar .sidebar-toggle{color:#fff}.skin-purple .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-purple .main-header .navbar .sidebar-toggle{color:#fff}.skin-purple .main-header .navbar .sidebar-toggle:hover{background-color:#555299}@media (max-width:767px){.skin-purple .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-purple .main-header .navbar .dropdown-menu li a{color:#fff}.skin-purple .main-header .navbar .dropdown-menu li a:hover{background:#555299}}.skin-purple .main-header .logo{background-color:#555299;color:#fff;border-bottom:0 solid transparent}.skin-purple .main-header .logo:hover{background-color:#545096}.skin-purple .main-header li.user-header{background-color:#605ca8}.skin-purple .content-header{background:transparent}.skin-purple .wrapper,.skin-purple .main-sidebar,.skin-purple .left-side{background-color:#222d32}.skin-purple .user-panel>.info,.skin-purple .user-panel>.info>a{color:#fff}.skin-purple .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-purple .sidebar-menu>li>a{border-left:3px solid transparent}.skin-purple .sidebar-menu>li:hover>a,.skin-purple .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#605ca8}.skin-purple .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-purple .sidebar a{color:#b8c7ce}.skin-purple .sidebar a:hover{text-decoration:none}.skin-purple .treeview-menu>li>a{color:#8aa4af}.skin-purple .treeview-menu>li.active>a,.skin-purple .treeview-menu>li>a:hover{color:#fff}.skin-purple .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-purple .sidebar-form input[type="text"],.skin-purple .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px}.skin-purple .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-purple .sidebar-form input[type="text"]:focus,.skin-purple .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-purple .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-purple .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-purple-light .main-header .navbar{background-color:#605ca8}.skin-purple-light .main-header .navbar .nav>li>a{color:#fff}.skin-purple-light .main-header .navbar .nav>li>a:hover,.skin-purple-light .main-header .navbar .nav>li>a:active,.skin-purple-light .main-header .navbar .nav>li>a:focus,.skin-purple-light .main-header .navbar .nav .open>a,.skin-purple-light .main-header .navbar .nav .open>a:hover,.skin-purple-light .main-header .navbar .nav .open>a:focus,.skin-purple-light .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-purple-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-purple-light .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-purple-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-purple-light .main-header .navbar .sidebar-toggle:hover{background-color:#555299}@media (max-width:767px){.skin-purple-light .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-purple-light .main-header .navbar .dropdown-menu li a{color:#fff}.skin-purple-light .main-header .navbar .dropdown-menu li a:hover{background:#555299}}.skin-purple-light .main-header .logo{background-color:#605ca8;color:#fff;border-bottom:0 solid transparent}.skin-purple-light .main-header .logo:hover{background-color:#5d59a6}.skin-purple-light .main-header li.user-header{background-color:#605ca8}.skin-purple-light .content-header{background:transparent}.skin-purple-light .wrapper,.skin-purple-light .main-sidebar,.skin-purple-light .left-side{background-color:#f9fafc}.skin-purple-light .content-wrapper,.skin-purple-light .main-footer{border-left:1px solid #d2d6de}.skin-purple-light .user-panel>.info,.skin-purple-light .user-panel>.info>a{color:#444}.skin-purple-light .sidebar-menu>li{-webkit-transition:border-left-color .3s ease;-o-transition:border-left-color .3s ease;transition:border-left-color .3s ease}.skin-purple-light .sidebar-menu>li.header{color:#848484;background:#f9fafc}.skin-purple-light .sidebar-menu>li>a{border-left:3px solid transparent;font-weight:600}.skin-purple-light .sidebar-menu>li:hover>a,.skin-purple-light .sidebar-menu>li.active>a{color:#000;background:#f4f4f5}.skin-purple-light .sidebar-menu>li.active{border-left-color:#605ca8}.skin-purple-light .sidebar-menu>li.active>a{font-weight:600}.skin-purple-light .sidebar-menu>li>.treeview-menu{background:#f4f4f5}.skin-purple-light .sidebar a{color:#444}.skin-purple-light .sidebar a:hover{text-decoration:none}.skin-purple-light .treeview-menu>li>a{color:#777}.skin-purple-light .treeview-menu>li.active>a,.skin-purple-light .treeview-menu>li>a:hover{color:#000}.skin-purple-light .treeview-menu>li.active>a{font-weight:600}.skin-purple-light .sidebar-form{border-radius:3px;border:1px solid #d2d6de;margin:10px 10px}.skin-purple-light .sidebar-form input[type="text"],.skin-purple-light .sidebar-form .btn{box-shadow:none;background-color:#fff;border:1px solid transparent;height:35px}.skin-purple-light .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-purple-light .sidebar-form input[type="text"]:focus,.skin-purple-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-purple-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-purple-light .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}@media (min-width:768px){.skin-purple-light.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{border-left:1px solid #d2d6de}} \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/css/bootstrap-table.min.css b/spring-boot-22-FarstPlus/src/main/resources/templates/static/css/bootstrap-table.min.css new file mode 100644 index 0000000..e3fffda --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/css/bootstrap-table.min.css @@ -0,0 +1 @@ +.fixed-table-container .bs-checkbox,.fixed-table-container .no-records-found{text-align:center}.fixed-table-body thead th .th-inner,.table td,.table th{box-sizing:border-box}.bootstrap-table .table{margin-bottom:0!important;border-bottom:1px solid #ddd;border-collapse:collapse!important;border-radius:1px}.bootstrap-table .table:not(.table-condensed),.bootstrap-table .table:not(.table-condensed)>tbody>tr>td,.bootstrap-table .table:not(.table-condensed)>tbody>tr>th,.bootstrap-table .table:not(.table-condensed)>tfoot>tr>td,.bootstrap-table .table:not(.table-condensed)>tfoot>tr>th,.bootstrap-table .table:not(.table-condensed)>thead>tr>td{padding:8px}.bootstrap-table .table.table-no-bordered>tbody>tr>td,.bootstrap-table .table.table-no-bordered>thead>tr>th{border-right:2px solid transparent}.bootstrap-table .table.table-no-bordered>tbody>tr>td:last-child{border-right:none}.fixed-table-container{position:relative;clear:both;border:1px solid #ddd;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px}.fixed-table-container.table-no-bordered{border:1px solid transparent}.fixed-table-footer,.fixed-table-header{overflow:hidden}.fixed-table-footer{border-top:1px solid #ddd}.fixed-table-body{overflow-x:auto;overflow-y:auto;height:100%}.fixed-table-container table{width:100%}.fixed-table-container thead th{height:0;padding:0;margin:0;border-left:1px solid #ddd}.fixed-table-container thead th:focus{outline:transparent solid 0}.fixed-table-container thead th:first-child{border-left:none;border-top-left-radius:4px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px}.fixed-table-container tbody td .th-inner,.fixed-table-container thead th .th-inner{padding:8px;line-height:24px;vertical-align:top;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fixed-table-container thead th .sortable{cursor:pointer;background-position:right;background-repeat:no-repeat;padding-right:30px}.fixed-table-container thead th .both{background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC')}.fixed-table-container thead th .asc{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBdqEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVoAADeemwtPcZI2wAAAABJRU5ErkJggg==)}.fixed-table-container thead th .desc{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWjYBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJzcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII=)}.fixed-table-container th.detail{width:30px}.fixed-table-container tbody td{border-left:1px solid #ddd}.fixed-table-container tbody tr:first-child td{border-top:none}.fixed-table-container tbody td:first-child{border-left:none}.fixed-table-container tbody .selected td{background-color:#f5f5f5}.fixed-table-container .bs-checkbox .th-inner{padding:8px 0}.fixed-table-container input[type=radio],.fixed-table-container input[type=checkbox]{margin:0 auto!important}.fixed-table-pagination .pagination-detail,.fixed-table-pagination div.pagination{margin-top:10px;margin-bottom:10px}.fixed-table-pagination div.pagination .pagination{margin:0}.fixed-table-pagination .pagination a{padding:6px 12px;line-height:1.428571429}.fixed-table-pagination .pagination-info{line-height:34px;margin-right:5px}.fixed-table-pagination .btn-group{position:relative;display:inline-block;vertical-align:middle}.fixed-table-pagination .dropup .dropdown-menu{margin-bottom:0}.fixed-table-pagination .page-list{display:inline-block}.fixed-table-toolbar .columns-left{margin-right:5px}.fixed-table-toolbar .columns-right{margin-left:5px}.fixed-table-toolbar .columns label{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.428571429}.fixed-table-toolbar .bs-bars,.fixed-table-toolbar .columns,.fixed-table-toolbar .search{position:relative;margin-top:0px;margin-bottom:0px;line-height:34px}.fixed-table-pagination li.disabled a{pointer-events:none;cursor:default}.fixed-table-loading{display:none;position:absolute;top:42px;right:0;bottom:0;left:0;z-index:99;background-color:#fff;text-align:center}.fixed-table-body .card-view .title{font-weight:700;display:inline-block;min-width:30%;text-align:left!important}.table td,.table th{vertical-align:middle}.fixed-table-toolbar .dropdown-menu{text-align:left;max-height:300px;overflow:auto}.fixed-table-toolbar .btn-group>.btn-group{display:inline-block;margin-left:-1px!important}.fixed-table-toolbar .btn-group>.btn-group>.btn{border-radius:0}.fixed-table-toolbar .btn-group>.btn-group:first-child>.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.fixed-table-toolbar .btn-group>.btn-group:last-child>.btn{border-top-right-radius:4px;border-bottom-right-radius:4px}.bootstrap-table .table>thead>tr>th{vertical-align:bottom;border-bottom:1px solid #ddd}.bootstrap-table .table thead>tr>th{padding:0;margin:0}.bootstrap-table .fixed-table-footer tbody>tr>td{padding:0!important}.bootstrap-table .fixed-table-footer .table{border-bottom:none;border-radius:0;padding:0!important}.bootstrap-table .pull-right .dropdown-menu{right:0;left:auto}p.fixed-table-scroll-inner{width:100%;height:200px}div.fixed-table-scroll-outer{top:0;left:0;visibility:hidden;width:200px;height:150px;overflow:hidden}.fixed-table-pagination:after,.fixed-table-toolbar:after{content:"";display:block;clear:both} \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/css/bootstrap.min.css b/spring-boot-22-FarstPlus/src/main/resources/templates/static/css/bootstrap.min.css new file mode 100644 index 0000000..ed3905e --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/css/bootstrap.min.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.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:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-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}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/css/font-awesome.min.css b/spring-boot-22-FarstPlus/src/main/resources/templates/static/css/font-awesome.min.css new file mode 100644 index 0000000..540440c --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/css/main.css b/spring-boot-22-FarstPlus/src/main/resources/templates/static/css/main.css new file mode 100644 index 0000000..a6ed176 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/css/main.css @@ -0,0 +1,54 @@ +html { overflow-x:hidden; } +.content-header { + position: relative; + padding: 0 0 3px 8px +} + +.content-header>.breadcrumb { + position: relative; + top: 0; + right: 0; + float: none; + margin-top: 0px; + padding-left: 10px; + background: #ecf0f5; +} + +.main-footer { + padding: 7px; + color: #444; + border-top: 1px solid #eee; +} + +[v-cloak] { + display: none; +} + +.grid-btn{ + margin-bottom:12px; +} +.grid-btn .btn{ + margin-right:10px; +} +.pointer{cursor: pointer;} + +.ml-10 { margin-left:0 !important; } +@media (min-width: 768px) { + .ml-10 { margin-left:10px !important; } + .col-sm-10 {width: 70%;padding-left: 0px;} + .col-sm-2 {width: 24%;} +} +tbody > tr > th {font-weight: normal; } +.panel .table { margin:0 0; } +.panel .pagination { margin:0; } +.panel-default>.panel-heading {background-color: #f5f5f5;} +.row{ + border-top: 1px solid #ddd; + margin:0; + padding:20px 2px 0px 2px; +} +.col-xs-6{padding-left: 0px;padding-right: 0px;} +.form-horizontal .form-group {margin-left:0px;margin-right:0px;} +.form-horizontal{ + width:550px;padding-top:20px; +} \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/favicon.ico b/spring-boot-22-FarstPlus/src/main/resources/templates/static/favicon.ico new file mode 100644 index 0000000..c30cbd9 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/favicon.ico differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/FontAwesome.otf b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/FontAwesome.otf new file mode 100644 index 0000000..401ec0f Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/FontAwesome.otf differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/fontawesome-webfont.eot b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/fontawesome-webfont.eot differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/fontawesome-webfont.svg b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/fontawesome-webfont.ttf b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/fontawesome-webfont.ttf differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/fontawesome-webfont.woff b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/fontawesome-webfont.woff differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/fontawesome-webfont.woff2 b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/fontawesome-webfont.woff2 differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/glyphicons-halflings-regular.eot b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 0000000..b93a495 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/glyphicons-halflings-regular.eot differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/glyphicons-halflings-regular.svg b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/glyphicons-halflings-regular.svg new file mode 100644 index 0000000..94fb549 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/glyphicons-halflings-regular.svg @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/glyphicons-halflings-regular.ttf b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 0000000..1413fc6 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/glyphicons-halflings-regular.ttf differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/glyphicons-halflings-regular.woff b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/glyphicons-halflings-regular.woff new file mode 100644 index 0000000..9e61285 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/glyphicons-halflings-regular.woff differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/glyphicons-halflings-regular.woff2 b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 0000000..64539b5 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/fonts/glyphicons-halflings-regular.woff2 differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/img/logoin-background.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/img/logoin-background.png new file mode 100644 index 0000000..31666bd Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/img/logoin-background.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/js/common.js b/spring-boot-22-FarstPlus/src/main/resources/templates/static/js/common.js new file mode 100644 index 0000000..e5b748f --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/js/common.js @@ -0,0 +1,110 @@ +//请求前缀 +var baseURL = "/fastplus/"; +//jqGrid的配置信息 +$.jgrid.defaults.width = 1000; +$.jgrid.defaults.responsive = true; +$.jgrid.defaults.styleUI = 'Bootstrap'; + +//工具集合Tools +window.T = {}; + +// 获取请求参数 +// 使用示例 +// location.href = http://localhost/index.html?id=123 +// T.p('id') --> 123; +var url = function(name) { + var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)"); + var r = window.location.search.substr(1).match(reg); + if(r!=null)return unescape(r[2]); return null; +}; +T.p = url; + +//登录token +var token = localStorage.getItem("token"); +if(token == 'null'){ + parent.location.href = baseURL + 'login.html'; +} + +//jquery全局配置 +$.ajaxSetup({ + dataType: "json", + cache: false, + headers: { + "token": token + }, + // xhrFields: { + // withCredentials: true + // }, + // complete: function(xhr) { + // //token过期,则跳转到登录页面 + // if(xhr.responseJSON.code == 401){ + // parent.location.href = baseURL + 'login.html'; + // } + // } +}); + +//jqgrid全局配置 +$.extend($.jgrid.defaults, { + ajaxGridOptions : { + headers: { + "token": token + } + } +}); + +//权限判断 +function hasPermission(permission) { + if (window.parent.permissions.indexOf(permission) > -1) { + return true; + } else { + return false; + } +} + +//重写alert +window.alert = function(msg, callback){ + parent.layer.alert(msg, function(index){ + parent.layer.close(index); + if(typeof(callback) === "function"){ + callback("ok"); + } + }); +} + +//重写confirm式样框 +window.confirm = function(msg, callback){ + parent.layer.confirm(msg, {btn: ['确定','取消']}, + function(){//确定事件 + if(typeof(callback) === "function"){ + callback("ok"); + } + }); +} + +//选择一条记录 +function getSelectedRow() { + var grid = $("#jqGrid"); + var rowKey = grid.getGridParam("selrow"); + if(!rowKey){ + alert("请选择一条记录"); + return ; + } + + var selectedIDs = grid.getGridParam("selarrrow"); + if(selectedIDs.length > 1){ + alert("只能选择一条记录"); + return ; + } + return selectedIDs[0]; +} + +//选择多条记录 +function getSelectedRows() { + var grid = $("#jqGrid"); + var rowKey = grid.getGridParam("selrow"); + if(!rowKey){ + alert("请选择一条记录"); + return ; + } + return grid.getGridParam("selarrrow"); +} \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/js/hdfs/hdfsapi.js b/spring-boot-22-FarstPlus/src/main/resources/templates/static/js/hdfs/hdfsapi.js new file mode 100644 index 0000000..39e2404 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/js/hdfs/hdfsapi.js @@ -0,0 +1,62 @@ +/** + * Created by timebusker on 2018/8/29. + */ +$(function () { + $("#jqGrid").jqGrid({ + url: baseURL + 'hdfs/list', + datatype: "json", + colModel: [ + { label: 'id', name: 'id', width: 20, key: true }, + { label: 'URL地址', name: 'url', width: 160 }, + { label: '创建时间', name: 'createDate', width: 40 } + ], + viewrecords: true, + height: 385, + rowNum: 10, + rowList : [10,30,50], + rownumbers: true, + rownumWidth: 25, + autowidth:true, + multiselect: true, + pager: "#jqGridPager", + jsonReader : { + root: "page.list", + page: "page.currPage", + total: "page.totalPage", + records: "page.totalCount" + }, + prmNames : { + page:"page", + rows:"limit", + order: "order" + }, + gridComplete:function(){ + //隐藏grid底部滚动条 + $("#jqGrid").closest(".ui-jqgrid-bdiv").css({ "overflow-x" : "hidden" }); + } + }); +}); + +var vm = new Vue({ + el:'#rrapp', + data:{ + showList: true, + title: null, + config: {} + }, + created: function(){ + this.query(); + }, + methods: { + query: function () { + vm.reload(); + }, + reload: function () { + vm.showList = true; + var page = $("#jqGrid").jqGrid('getGridParam','page'); + $("#jqGrid").jqGrid('setGridParam',{ + page:page + }).trigger("reloadGrid"); + } + } +}); \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/js/index.js b/spring-boot-22-FarstPlus/src/main/resources/templates/static/js/index.js new file mode 100644 index 0000000..dd277b7 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/js/index.js @@ -0,0 +1,50 @@ +//iframe自适应 +$(window).on('resize', function() { + var $content = $('.content'); + $content.height($(this).height() - 120); + $content.find('iframe').each(function() { + $(this).height($content.height()); + }); +}).resize(); + +var vm = new Vue({ + el:'#rrapp', + data:{ + user:{}, + menuList:{}, + main:"main.html", + password:'', + newPassword:'', + navTitle:"欢迎页" + }, + methods: { + getMenuList: function () { + //路由 + var router = new Router(); + routerList(router); + router.start(); + } + }, + created: function(){ + this.getMenuList(); + } +}); + +function routerList(router) { + $("#all_memu").find("a").each(function () { + var href = $(this).attr("href").toString(); + if (href.indexOf('#' == 0)) { + router.add(href, function () { + var url = window.location.hash; + console.log(url); + //替换iframe的url + vm.main = url.replace('#', ''); + //导航菜单展开 + $(".treeview-menu li").removeClass("active"); + $(".sidebar-menu li").removeClass("active"); + $("a[href='" + url + "']").parents("li").addClass("active"); + vm.navTitle = $("a[href='" + url + "']").text(); + }); + } + }); +} \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/libs/ajaxupload.js b/spring-boot-22-FarstPlus/src/main/resources/templates/static/libs/ajaxupload.js new file mode 100644 index 0000000..7e51768 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/libs/ajaxupload.js @@ -0,0 +1,673 @@ +/** + * AJAX Upload ( http://valums.com/ajax-upload/ ) + * Copyright (c) Andris Valums + * Licensed under the MIT license ( http://valums.com/mit-license/ ) + * Thanks to Gary Haran, David Mark, Corey Burns and others for contributions + */ +(function () { + /* global window */ + /* jslint browser: true, devel: true, undef: true, nomen: true, bitwise: true, regexp: true, newcap: true, immed: true */ + + /** + * Wrapper for FireBug's console.log + */ + function log(){ + if (typeof(console) != 'undefined' && typeof(console.log) == 'function'){ + Array.prototype.unshift.call(arguments, '[Ajax Upload]'); + console.log( Array.prototype.join.call(arguments, ' ')); + } + } + + /** + * Attaches event to a dom element. + * @param {Element} el + * @param type event name + * @param fn callback This refers to the passed element + */ + function addEvent(el, type, fn){ + if (el.addEventListener) { + el.addEventListener(type, fn, false); + } else if (el.attachEvent) { + el.attachEvent('on' + type, function(){ + fn.call(el); + }); + } else { + throw new Error('not supported or DOM not loaded'); + } + } + + /** + * Attaches resize event to a window, limiting + * number of event fired. Fires only when encounteres + * delay of 100 after series of events. + * + * Some browsers fire event multiple times when resizing + * http://www.quirksmode.org/dom/events/resize.html + * + * @param fn callback This refers to the passed element + */ + function addResizeEvent(fn){ + var timeout; + + addEvent(window, 'resize', function(){ + if (timeout){ + clearTimeout(timeout); + } + timeout = setTimeout(fn, 100); + }); + } + + // Needs more testing, will be rewriten for next version + // getOffset function copied from jQuery lib (http://jquery.com/) + if (document.documentElement.getBoundingClientRect){ + // Get Offset using getBoundingClientRect + // http://ejohn.org/blog/getboundingclientrect-is-awesome/ + var getOffset = function(el){ + var box = el.getBoundingClientRect(); + var doc = el.ownerDocument; + var body = doc.body; + var docElem = doc.documentElement; // for ie + var clientTop = docElem.clientTop || body.clientTop || 0; + var clientLeft = docElem.clientLeft || body.clientLeft || 0; + + // In Internet Explorer 7 getBoundingClientRect property is treated as physical, + // while others are logical. Make all logical, like in IE8. + var zoom = 1; + if (body.getBoundingClientRect) { + var bound = body.getBoundingClientRect(); + zoom = (bound.right - bound.left) / body.clientWidth; + } + + if (zoom > 1) { + clientTop = 0; + clientLeft = 0; + } + + var top = box.top / zoom + (window.pageYOffset || docElem && docElem.scrollTop / zoom || body.scrollTop / zoom) - clientTop, left = box.left / zoom + (window.pageXOffset || docElem && docElem.scrollLeft / zoom || body.scrollLeft / zoom) - clientLeft; + + return { + top: top, + left: left + }; + }; + } else { + // Get offset adding all offsets + var getOffset = function(el){ + var top = 0, left = 0; + do { + top += el.offsetTop || 0; + left += el.offsetLeft || 0; + el = el.offsetParent; + } while (el); + + return { + left: left, + top: top + }; + }; + } + + /** + * Returns left, top, right and bottom properties describing the border-box, + * in pixels, with the top-left relative to the body + * @param {Element} el + * @return {Object} Contains left, top, right,bottom + */ + function getBox(el){ + var left, right, top, bottom; + var offset = getOffset(el); + left = offset.left; + top = offset.top; + + right = left + el.offsetWidth; + bottom = top + el.offsetHeight; + + return { + left: left, + right: right, + top: top, + bottom: bottom + }; + } + + /** + * Helper that takes object literal + * and add all properties to element.style + * @param {Element} el + * @param {Object} styles + */ + function addStyles(el, styles){ + for (var name in styles) { + if (styles.hasOwnProperty(name)) { + el.style[name] = styles[name]; + } + } + } + + /** + * Function places an absolutely positioned + * element on top of the specified element + * copying position and dimentions. + * @param {Element} from + * @param {Element} to + */ + function copyLayout(from, to){ + var box = getBox(from); + + addStyles(to, { + position: 'absolute', + left : box.left + 'px', + top : box.top + 'px', + width : from.offsetWidth + 'px', + height : from.offsetHeight + 'px' + }); + } + + /** + * Creates and returns element from html chunk + * Uses innerHTML to create an element + */ + var toElement = (function(){ + var div = document.createElement('div'); + return function(html){ + div.innerHTML = html; + var el = div.firstChild; + return div.removeChild(el); + }; + })(); + + /** + * Function generates unique id + * @return unique id + */ + var getUID = (function(){ + var id = 0; + return function(){ + return 'ValumsAjaxUpload' + id++; + }; + })(); + + /** + * Get file name from path + * @param {String} file path to file + * @return filename + */ + function fileFromPath(file){ + return file.replace(/.*(\/|\\)/, ""); + } + + /** + * Get file extension lowercase + * @param {String} file name + * @return file extenstion + */ + function getExt(file){ + return (-1 !== file.indexOf('.')) ? file.replace(/.*[.]/, '') : ''; + } + + function hasClass(el, name){ + var re = new RegExp('\\b' + name + '\\b'); + return re.test(el.className); + } + function addClass(el, name){ + if ( ! hasClass(el, name)){ + el.className += ' ' + name; + } + } + function removeClass(el, name){ + var re = new RegExp('\\b' + name + '\\b'); + el.className = el.className.replace(re, ''); + } + + function removeNode(el){ + el.parentNode.removeChild(el); + } + + /** + * Easy styling and uploading + * @constructor + * @param button An element you want convert to + * upload button. Tested dimentions up to 500x500px + * @param {Object} options See defaults below. + */ + window.AjaxUpload = function(button, options){ + this._settings = { + // Location of the server-side upload script + action: 'upload.php', + // File upload name + name: 'userfile', + // Additional data to send + data: {}, + // Submit file as soon as it's selected + autoSubmit: true, + // The type of data that you're expecting back from the server. + // html and xml are detected automatically. + // Only useful when you are using json data as a response. + // Set to "json" in that case. + responseType: false, + // Class applied to button when mouse is hovered + hoverClass: 'hover', + // Class applied to button when AU is disabled + disabledClass: 'disabled', + // When user selects a file, useful with autoSubmit disabled + // You can return false to cancel upload + onChange: function(file, extension){ + }, + // Callback to fire before file is uploaded + // You can return false to cancel upload + onSubmit: function(file, extension){ + }, + // Fired when file upload is completed + // WARNING! DO NOT USE "FALSE" STRING AS A RESPONSE! + onComplete: function(file, response){ + } + }; + + // Merge the users options with our defaults + for (var i in options) { + if (options.hasOwnProperty(i)){ + this._settings[i] = options[i]; + } + } + + // button isn't necessary a dom element + if (button.jquery){ + // jQuery object was passed + button = button[0]; + } else if (typeof button == "string") { + if (/^#.*/.test(button)){ + // If jQuery user passes #elementId don't break it + button = button.slice(1); + } + + button = document.getElementById(button); + } + + if ( ! button || button.nodeType !== 1){ + throw new Error("Please make sure that you're passing a valid element"); + } + + if ( button.nodeName.toUpperCase() == 'A'){ + // disable link + addEvent(button, 'click', function(e){ + if (e && e.preventDefault){ + e.preventDefault(); + } else if (window.event){ + window.event.returnValue = false; + } + }); + } + + // DOM element + this._button = button; + // DOM element + this._input = null; + // If disabled clicking on button won't do anything + this._disabled = false; + + // if the button was disabled before refresh if will remain + // disabled in FireFox, let's fix it + this.enable(); + + this._rerouteClicks(); + }; + + // assigning methods to our class + AjaxUpload.prototype = { + setData: function(data){ + this._settings.data = data; + }, + disable: function(){ + addClass(this._button, this._settings.disabledClass); + this._disabled = true; + + var nodeName = this._button.nodeName.toUpperCase(); + if (nodeName == 'INPUT' || nodeName == 'BUTTON'){ + this._button.setAttribute('disabled', 'disabled'); + } + + // hide input + if (this._input){ + // We use visibility instead of display to fix problem with Safari 4 + // The problem is that the value of input doesn't change if it + // has display none when user selects a file + this._input.parentNode.style.visibility = 'hidden'; + } + }, + enable: function(){ + removeClass(this._button, this._settings.disabledClass); + this._button.removeAttribute('disabled'); + this._disabled = false; + + }, + /** + * Creates invisible file input + * that will hover above the button + *
+ */ + _createInput: function(){ + var self = this; + + var input = document.createElement("input"); + input.setAttribute('type', 'file'); + input.setAttribute('name', this._settings.name); + + addStyles(input, { + 'position' : 'absolute', + // in Opera only 'browse' button + // is clickable and it is located at + // the right side of the input + 'right' : 0, + 'margin' : 0, + 'padding' : 0, + 'fontSize' : '480px', + 'cursor' : 'pointer' + }); + + var div = document.createElement("div"); + addStyles(div, { + 'display' : 'block', + 'position' : 'absolute', + 'overflow' : 'hidden', + 'margin' : 0, + 'padding' : 0, + 'opacity' : 0, + // Make sure browse button is in the right side + // in Internet Explorer + 'direction' : 'ltr', + //Max zIndex supported by Opera 9.0-9.2 + 'zIndex': 2147483583 + }); + + // Make sure that element opacity exists. + // Otherwise use IE filter + if ( div.style.opacity !== "0") { + if (typeof(div.filters) == 'undefined'){ + throw new Error('Opacity not supported by the browser'); + } + div.style.filter = "alpha(opacity=0)"; + } + + addEvent(input, 'change', function(){ + + if ( ! input || input.value === ''){ + return; + } + + // Get filename from input, required + // as some browsers have path instead of it + var file = fileFromPath(input.value); + + if (false === self._settings.onChange.call(self, file, getExt(file))){ + self._clearInput(); + return; + } + + // Submit form when value is changed + if (self._settings.autoSubmit) { + self.submit(); + } + }); + + addEvent(input, 'mouseover', function(){ + addClass(self._button, self._settings.hoverClass); + }); + + addEvent(input, 'mouseout', function(){ + removeClass(self._button, self._settings.hoverClass); + + // We use visibility instead of display to fix problem with Safari 4 + // The problem is that the value of input doesn't change if it + // has display none when user selects a file + input.parentNode.style.visibility = 'hidden'; + + }); + + div.appendChild(input); + document.body.appendChild(div); + + this._input = input; + }, + _clearInput : function(){ + if (!this._input){ + return; + } + + // this._input.value = ''; Doesn't work in IE6 + removeNode(this._input.parentNode); + this._input = null; + this._createInput(); + + removeClass(this._button, this._settings.hoverClass); + }, + /** + * Function makes sure that when user clicks upload button, + * the this._input is clicked instead + */ + _rerouteClicks: function(){ + var self = this; + + // IE will later display 'access denied' error + // if you use using self._input.click() + // other browsers just ignore click() + + addEvent(self._button, 'mouseover', function(){ + if (self._disabled){ + return; + } + + if ( ! self._input){ + self._createInput(); + } + + var div = self._input.parentNode; + copyLayout(self._button, div); + div.style.visibility = 'visible'; + + }); + + + // commented because we now hide input on mouseleave + /** + * When the window is resized the elements + * can be misaligned if button position depends + * on window size + */ + //addResizeEvent(function(){ + // if (self._input){ + // copyLayout(self._button, self._input.parentNode); + // } + //}); + + }, + /** + * Creates iframe with unique name + * @return {Element} iframe + */ + _createIframe: function(){ + // We can't use getTime, because it sometimes return + // same value in safari :( + var id = getUID(); + + // We can't use following code as the name attribute + // won't be properly registered in IE6, and new window + // on form submit will open + // var iframe = document.createElement('iframe'); + // iframe.setAttribute('name', id); + + var iframe = toElement('';break;case 3:delete t.title,delete t.closeBtn,t.icon===-1&&0===t.icon,r.closeAll("loading");break;case 4:f||(t.content=[t.content,"body"]),t.follow=t.content[1],t.content=t.content[0]+'',delete t.title,t.tips="object"==typeof t.tips?t.tips:[t.tips,!0],t.tipsMore||r.closeAll("tips")}e.vessel(f,function(n,r,d){c.append(n[0]),f?function(){2==t.type||4==t.type?function(){i("body").append(n[1])}():function(){l.parents("."+s[0])[0]||(l.data("display",l.css("display")).show().addClass("layui-layer-wrap").wrap(n[1]),i("#"+s[0]+a).find("."+s[5]).before(r))}()}():c.append(n[1]),i(".layui-layer-move")[0]||c.append(o.moveElem=d),e.layero=i("#"+s[0]+a),t.scrollbar||s.html.css("overflow","hidden").attr("layer-full",a)}).auto(a),2==t.type&&6==r.ie&&e.layero.find("iframe").attr("src",l[0]),4==t.type?e.tips():e.offset(),t.fixed&&n.on("resize",function(){e.offset(),(/^\d+%$/.test(t.area[0])||/^\d+%$/.test(t.area[1]))&&e.auto(a),4==t.type&&e.tips()}),t.time<=0||setTimeout(function(){r.close(e.index)},t.time),e.move().callback(),s.anim[t.anim]&&e.layero.addClass(s.anim[t.anim]).data("anim",!0)}},l.pt.auto=function(e){function t(e){e=l.find(e),e.height(f[1]-c-d-2*(0|parseFloat(e.css("padding"))))}var a=this,o=a.config,l=i("#"+s[0]+e);""===o.area[0]&&o.maxWidth>0&&(r.ie&&r.ie<8&&o.btn&&l.width(l.innerWidth()),l.outerWidth()>o.maxWidth&&l.width(o.maxWidth));var f=[l.innerWidth(),l.innerHeight()],c=l.find(s[1]).outerHeight()||0,d=l.find("."+s[6]).outerHeight()||0;switch(o.type){case 2:t("iframe");break;default:""===o.area[1]?o.fixed&&f[1]>=n.height()&&(f[1]=n.height(),t("."+s[5])):t("."+s[5])}return a},l.pt.offset=function(){var e=this,t=e.config,i=e.layero,a=[i.outerWidth(),i.outerHeight()],o="object"==typeof t.offset;e.offsetTop=(n.height()-a[1])/2,e.offsetLeft=(n.width()-a[0])/2,o?(e.offsetTop=t.offset[0],e.offsetLeft=t.offset[1]||e.offsetLeft):"auto"!==t.offset&&("t"===t.offset?e.offsetTop=0:"r"===t.offset?e.offsetLeft=n.width()-a[0]:"b"===t.offset?e.offsetTop=n.height()-a[1]:"l"===t.offset?e.offsetLeft=0:"lt"===t.offset?(e.offsetTop=0,e.offsetLeft=0):"lb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=0):"rt"===t.offset?(e.offsetTop=0,e.offsetLeft=n.width()-a[0]):"rb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=n.width()-a[0]):e.offsetTop=t.offset),t.fixed||(e.offsetTop=/%$/.test(e.offsetTop)?n.height()*parseFloat(e.offsetTop)/100:parseFloat(e.offsetTop),e.offsetLeft=/%$/.test(e.offsetLeft)?n.width()*parseFloat(e.offsetLeft)/100:parseFloat(e.offsetLeft),e.offsetTop+=n.scrollTop(),e.offsetLeft+=n.scrollLeft()),i.attr("minLeft")&&(e.offsetTop=n.height()-(i.find(s[1]).outerHeight()||0),e.offsetLeft=i.css("left")),i.css({top:e.offsetTop,left:e.offsetLeft})},l.pt.tips=function(){var e=this,t=e.config,a=e.layero,o=[a.outerWidth(),a.outerHeight()],r=i(t.follow);r[0]||(r=i("body"));var l={width:r.outerWidth(),height:r.outerHeight(),top:r.offset().top,left:r.offset().left},f=a.find(".layui-layer-TipsG"),c=t.tips[0];t.tips[1]||f.remove(),l.autoLeft=function(){l.left+o[0]-n.width()>0?(l.tipLeft=l.left+l.width-o[0],f.css({right:12,left:"auto"})):l.tipLeft=l.left},l.where=[function(){l.autoLeft(),l.tipTop=l.top-o[1]-10,f.removeClass("layui-layer-TipsB").addClass("layui-layer-TipsT").css("border-right-color",t.tips[1])},function(){l.tipLeft=l.left+l.width+10,l.tipTop=l.top,f.removeClass("layui-layer-TipsL").addClass("layui-layer-TipsR").css("border-bottom-color",t.tips[1])},function(){l.autoLeft(),l.tipTop=l.top+l.height+10,f.removeClass("layui-layer-TipsT").addClass("layui-layer-TipsB").css("border-right-color",t.tips[1])},function(){l.tipLeft=l.left-o[0]-10,l.tipTop=l.top,f.removeClass("layui-layer-TipsR").addClass("layui-layer-TipsL").css("border-bottom-color",t.tips[1])}],l.where[c-1](),1===c?l.top-(n.scrollTop()+o[1]+16)<0&&l.where[2]():2===c?n.width()-(l.left+l.width+o[0]+16)>0||l.where[3]():3===c?l.top-n.scrollTop()+l.height+o[1]+16-n.height()>0&&l.where[0]():4===c&&o[0]+16-l.left>0&&l.where[1](),a.find("."+s[5]).css({"background-color":t.tips[1],"padding-right":t.closeBtn?"30px":""}),a.css({left:l.tipLeft-(t.fixed?n.scrollLeft():0),top:l.tipTop-(t.fixed?n.scrollTop():0)})},l.pt.move=function(){var e=this,t=e.config,a=i(document),l=e.layero,s=l.find(t.move),f=l.find(".layui-layer-resize"),c={};return t.move&&s.css("cursor","move"),s.on("mousedown",function(e){e.preventDefault(),t.move&&(c.moveStart=!0,c.offset=[e.clientX-parseFloat(l.css("left")),e.clientY-parseFloat(l.css("top"))],o.moveElem.css("cursor","move").show())}),f.on("mousedown",function(e){e.preventDefault(),c.resizeStart=!0,c.offset=[e.clientX,e.clientY],c.area=[l.outerWidth(),l.outerHeight()],o.moveElem.css("cursor","se-resize").show()}),a.on("mousemove",function(i){if(c.moveStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1],s="fixed"===l.css("position");if(i.preventDefault(),c.stX=s?0:n.scrollLeft(),c.stY=s?0:n.scrollTop(),!t.moveOut){var f=n.width()-l.outerWidth()+c.stX,d=n.height()-l.outerHeight()+c.stY;af&&(a=f),od&&(o=d)}l.css({left:a,top:o})}if(t.resize&&c.resizeStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1];i.preventDefault(),r.style(e.index,{width:c.area[0]+a,height:c.area[1]+o}),c.isResize=!0}}).on("mouseup",function(e){c.moveStart&&(delete c.moveStart,o.moveElem.hide(),t.moveEnd&&t.moveEnd()),c.resizeStart&&(delete c.resizeStart,o.moveElem.hide())}),e},l.pt.callback=function(){function e(){var e=a.cancel&&a.cancel(t.index,n);e===!1||r.close(t.index)}var t=this,n=t.layero,a=t.config;t.openLayer(),a.success&&(2==a.type?n.find("iframe").on("load",function(){a.success(n,t.index)}):a.success(n,t.index)),6==r.ie&&t.IE6(n),n.find("."+s[6]).children("a").on("click",function(){var e=i(this).index();if(0===e)a.yes?a.yes(t.index,n):a.btn1?a.btn1(t.index,n):r.close(t.index);else{var o=a["btn"+(e+1)]&&a["btn"+(e+1)](t.index,n);o===!1||r.close(t.index)}}),n.find("."+s[7]).on("click",e),a.shadeClose&&i("#layui-layer-shade"+t.index).on("click",function(){r.close(t.index)}),n.find(".layui-layer-min").on("click",function(){var e=a.min&&a.min(n);e===!1||r.min(t.index,a)}),n.find(".layui-layer-max").on("click",function(){i(this).hasClass("layui-layer-maxmin")?(r.restore(t.index),a.restore&&a.restore(n)):(r.full(t.index,a),setTimeout(function(){a.full&&a.full(n)},100))}),a.end&&(o.end[t.index]=a.end)},o.reselect=function(){i.each(i("select"),function(e,t){var n=i(this);n.parents("."+s[0])[0]||1==n.attr("layer")&&i("."+s[0]).length<1&&n.removeAttr("layer").show(),n=null})},l.pt.IE6=function(e){i("select").each(function(e,t){var n=i(this);n.parents("."+s[0])[0]||"none"===n.css("display")||n.attr({layer:"1"}).hide(),n=null})},l.pt.openLayer=function(){var e=this;r.zIndex=e.config.zIndex,r.setTop=function(e){var t=function(){r.zIndex++,e.css("z-index",r.zIndex+1)};return r.zIndex=parseInt(e[0].style.zIndex),e.on("mousedown",t),r.zIndex}},o.record=function(e){var t=[e.width(),e.height(),e.position().top,e.position().left+parseFloat(e.css("margin-left"))];e.find(".layui-layer-max").addClass("layui-layer-maxmin"),e.attr({area:t})},o.rescollbar=function(e){s.html.attr("layer-full")==e&&(s.html[0].style.removeProperty?s.html[0].style.removeProperty("overflow"):s.html[0].style.removeAttribute("overflow"),s.html.removeAttr("layer-full"))},e.layer=r,r.getChildFrame=function(e,t){return t=t||i("."+s[4]).attr("times"),i("#"+s[0]+t).find("iframe").contents().find(e)},r.getFrameIndex=function(e){return i("#"+e).parents("."+s[4]).attr("times")},r.iframeAuto=function(e){if(e){var t=r.getChildFrame("html",e).outerHeight(),n=i("#"+s[0]+e),a=n.find(s[1]).outerHeight()||0,o=n.find("."+s[6]).outerHeight()||0;n.css({height:t+a+o}),n.find("iframe").css({height:t})}},r.iframeSrc=function(e,t){i("#"+s[0]+e).find("iframe").attr("src",t)},r.style=function(e,t,n){var a=i("#"+s[0]+e),r=a.find(".layui-layer-content"),l=a.attr("type"),f=a.find(s[1]).outerHeight()||0,c=a.find("."+s[6]).outerHeight()||0;a.attr("minLeft");l!==o.type[3]&&l!==o.type[4]&&(n||(parseFloat(t.width)<=260&&(t.width=260),parseFloat(t.height)-f-c<=64&&(t.height=64+f+c)),a.css(t),c=a.find("."+s[6]).outerHeight(),l===o.type[2]?a.find("iframe").css({height:parseFloat(t.height)-f-c}):r.css({height:parseFloat(t.height)-f-c-parseFloat(r.css("padding-top"))-parseFloat(r.css("padding-bottom"))}))},r.min=function(e,t){var a=i("#"+s[0]+e),l=a.find(s[1]).outerHeight()||0,f=a.attr("minLeft")||181*o.minIndex+"px",c=a.css("position");o.record(a),o.minLeft[0]&&(f=o.minLeft[0],o.minLeft.shift()),a.attr("position",c),r.style(e,{width:180,height:l,left:f,top:n.height()-l,position:"fixed",overflow:"hidden"},!0),a.find(".layui-layer-min").hide(),"page"===a.attr("type")&&a.find(s[4]).hide(),o.rescollbar(e),a.attr("minLeft")||o.minIndex++,a.attr("minLeft",f)},r.restore=function(e){var t=i("#"+s[0]+e),n=t.attr("area").split(",");t.attr("type");r.style(e,{width:parseFloat(n[0]),height:parseFloat(n[1]),top:parseFloat(n[2]),left:parseFloat(n[3]),position:t.attr("position"),overflow:"visible"},!0),t.find(".layui-layer-max").removeClass("layui-layer-maxmin"),t.find(".layui-layer-min").show(),"page"===t.attr("type")&&t.find(s[4]).show(),o.rescollbar(e)},r.full=function(e){var t,a=i("#"+s[0]+e);o.record(a),s.html.attr("layer-full")||s.html.css("overflow","hidden").attr("layer-full",e),clearTimeout(t),t=setTimeout(function(){var t="fixed"===a.css("position");r.style(e,{top:t?0:n.scrollTop(),left:t?0:n.scrollLeft(),width:n.width(),height:n.height()},!0),a.find(".layui-layer-min").hide()},100)},r.title=function(e,t){var n=i("#"+s[0]+(t||r.index)).find(s[1]);n.html(e)},r.close=function(e){var t=i("#"+s[0]+e),n=t.attr("type"),a="layer-anim-close";if(t[0]){var l="layui-layer-wrap",f=function(){if(n===o.type[1]&&"object"===t.attr("conType")){t.children(":not(."+s[5]+")").remove();for(var a=t.find("."+l),r=0;r<2;r++)a.unwrap();a.css("display",a.data("display")).removeClass(l)}else{if(n===o.type[2])try{var f=i("#"+s[4]+e)[0];f.contentWindow.document.write(""),f.contentWindow.close(),t.find("."+s[5])[0].removeChild(f)}catch(c){}t[0].innerHTML="",t.remove()}};t.data("anim")&&t.addClass(a),i("#layui-layer-moves, #layui-layer-shade"+e).remove(),6==r.ie&&o.reselect(),o.rescollbar(e),"function"==typeof o.end[e]&&o.end[e](),delete o.end[e],t.attr("minLeft")&&(o.minIndex--,o.minLeft.push(t.attr("minLeft"))),setTimeout(function(){f()},r.ie&&r.ie<10||!t.data("anim")?0:200)}},r.closeAll=function(e){i.each(i("."+s[0]),function(){var t=i(this),n=e?t.attr("type")===e:1;n&&r.close(t.attr("times")),n=null})};var f=r.cache||{},c=function(e){return f.skin?" "+f.skin+" "+f.skin+"-"+e:""};r.prompt=function(e,t){var a="";if(e=e||{},"function"==typeof e&&(t=e),e.area){var o=e.area;a='style="width: '+o[0]+"; height: "+o[1]+';"',delete e.area}var l,s=2==e.formType?'":function(){return''}();return r.open(i.extend({type:1,btn:["确定","取消"],content:s,skin:"layui-layer-prompt"+c("prompt"),maxWidth:n.width(),success:function(e){l=e.find(".layui-layer-input"),l.focus()},resize:!1,yes:function(i){var n=l.val();""===n?l.focus():n.length>(e.maxlength||500)?r.tips("最多输入"+(e.maxlength||500)+"个字数",l,{tips:1}):t&&t(n,i,l)}},e))},r.tab=function(e){e=e||{};var t=e.tab||{};return r.open(i.extend({type:1,skin:"layui-layer-tab"+c("tab"),resize:!1,title:function(){var e=t.length,i=1,n="";if(e>0)for(n=''+t[0].title+"";i"+t[i].title+"";return n}(),content:'
    '+function(){var e=t.length,i=1,n="";if(e>0)for(n='
  • '+(t[0].content||"no content")+"
  • ";i'+(t[i].content||"no content")+"";return n}()+"
",success:function(t){var n=t.find(".layui-layer-title").children(),a=t.find(".layui-layer-tabmain").children();n.on("mousedown",function(t){t.stopPropagation?t.stopPropagation():t.cancelBubble=!0;var n=i(this),o=n.index();n.addClass("layui-layer-tabnow").siblings().removeClass("layui-layer-tabnow"),a.eq(o).show().siblings().hide(),"function"==typeof e.change&&e.change(o)})}},e))},r.photos=function(t,n,a){function o(e,t,i){var n=new Image;return n.src=e,n.complete?t(n):(n.onload=function(){n.onload=null,t(n)},void(n.onerror=function(e){n.onerror=null,i(e)}))}var l={};if(t=t||{},t.photos){var s=t.photos.constructor===Object,f=s?t.photos:{},d=f.data||[],u=f.start||0;if(l.imgIndex=(0|u)+1,t.img=t.img||"img",s){if(0===d.length)return r.msg("没有图片")}else{var y=i(t.photos),p=function(){d=[],y.find(t.img).each(function(e){var t=i(this);t.attr("layer-index",e),d.push({alt:t.attr("alt"),pid:t.attr("layer-pid"),src:t.attr("layer-src")||t.attr("src"),thumb:t.attr("src")})})};if(p(),0===d.length)return;if(n||y.on("click",t.img,function(){var e=i(this),n=e.attr("layer-index");r.photos(i.extend(t,{photos:{start:n,data:d,tab:t.tab},full:t.full}),!0),p()}),!n)return}l.imgprev=function(e){l.imgIndex--,l.imgIndex<1&&(l.imgIndex=d.length),l.tabimg(e)},l.imgnext=function(e,t){l.imgIndex++,l.imgIndex>d.length&&(l.imgIndex=1,t)||l.tabimg(e)},l.keyup=function(e){if(!l.end){var t=e.keyCode;e.preventDefault(),37===t?l.imgprev(!0):39===t?l.imgnext(!0):27===t&&r.close(l.index)}},l.tabimg=function(e){d.length<=1||(f.start=l.imgIndex-1,r.close(l.index),r.photos(t,!0,e))},l.event=function(){l.bigimg.hover(function(){l.imgsee.show()},function(){l.imgsee.hide()}),l.bigimg.find(".layui-layer-imgprev").on("click",function(e){e.preventDefault(),l.imgprev()}),l.bigimg.find(".layui-layer-imgnext").on("click",function(e){e.preventDefault(),l.imgnext()}),i(document).on("keyup",l.keyup)},l.loadi=r.load(1,{shade:!("shade"in t)&&.9,scrollbar:!1}),o(d[u].src,function(n){r.close(l.loadi),l.index=r.open(i.extend({type:1,area:function(){var a=[n.width,n.height],o=[i(e).width()-100,i(e).height()-100];if(!t.full&&(a[0]>o[0]||a[1]>o[1])){var r=[a[0]/o[0],a[1]/o[1]];r[0]>r[1]?(a[0]=a[0]/r[0],a[1]=a[1]/r[0]):r[0]'+(d[u].alt||
'+(d.length>1?'':"")+'
'+(d[u].alt||"")+""+l.imgIndex+"/"+d.length+"
",success:function(e,i){l.bigimg=e.find(".layui-layer-phimg"),l.imgsee=e.find(".layui-layer-imguide,.layui-layer-imgbar"),l.event(e),t.tab&&t.tab(d[u],e)},end:function(){l.end=!0,i(document).off("keyup",l.keyup)}},t))},function(){r.close(l.loadi),r.msg("当前图片地址异常
是否继续查看下一张?",{time:3e4,btn:["下一张","不看了"],yes:function(){d.length>1&&l.imgnext(!0,!0)}})})}},o.run=function(t){i=t,n=i(e),s.html=i("html"),r.open=function(e){var t=new l(e);return t.index}},e.layui&&layui.define?(r.ready(),layui.define("jquery",function(t){r.path=layui.cache.dir,o.run(layui.jquery),e.layer=r,t("layer",r)})):"function"==typeof define?define(["jquery"],function(){return o.run(e.jQuery),r}):function(){o.run(e.jQuery),r.ready()}()}(window); \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/mobile/layer.js b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/mobile/layer.js new file mode 100644 index 0000000..f9cf693 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/mobile/layer.js @@ -0,0 +1,2 @@ +/*! layer mobile-v2.0.0 Web弹层组件 MIT License http://layer.layui.com/mobile By 贤心 */ + ;!function(e){"use strict";var t=document,n="querySelectorAll",i="getElementsByClassName",a=function(e){return t[n](e)},s={type:0,shade:!0,shadeClose:!0,fixed:!0,anim:"scale"},l={extend:function(e){var t=JSON.parse(JSON.stringify(s));for(var n in e)t[n]=e[n];return t},timer:{},end:{}};l.touch=function(e,t){e.addEventListener("click",function(e){t.call(this,e)},!1)};var r=0,o=["layui-m-layer"],c=function(e){var t=this;t.config=l.extend(e),t.view()};c.prototype.view=function(){var e=this,n=e.config,s=t.createElement("div");e.id=s.id=o[0]+r,s.setAttribute("class",o[0]+" "+o[0]+(n.type||0)),s.setAttribute("index",r);var l=function(){var e="object"==typeof n.title;return n.title?'

'+(e?n.title[0]:n.title)+"

":""}(),c=function(){"string"==typeof n.btn&&(n.btn=[n.btn]);var e,t=(n.btn||[]).length;return 0!==t&&n.btn?(e=''+n.btn[0]+"",2===t&&(e=''+n.btn[1]+""+e),'
'+e+"
"):""}();if(n.fixed||(n.top=n.hasOwnProperty("top")?n.top:100,n.style=n.style||"",n.style+=" top:"+(t.body.scrollTop+n.top)+"px"),2===n.type&&(n.content='

'+(n.content||"")+"

"),n.skin&&(n.anim="up"),"msg"===n.skin&&(n.shade=!1),s.innerHTML=(n.shade?"
':"")+'
"+l+'
'+n.content+"
"+c+"
",!n.type||2===n.type){var d=t[i](o[0]+n.type),y=d.length;y>=1&&layer.close(d[0].getAttribute("index"))}document.body.appendChild(s);var u=e.elem=a("#"+e.id)[0];n.success&&n.success(u),e.index=r++,e.action(n,u)},c.prototype.action=function(e,t){var n=this;e.time&&(l.timer[n.index]=setTimeout(function(){layer.close(n.index)},1e3*e.time));var a=function(){var t=this.getAttribute("type");0==t?(e.no&&e.no(),layer.close(n.index)):e.yes?e.yes(n.index):layer.close(n.index)};if(e.btn)for(var s=t[i]("layui-m-layerbtn")[0].children,r=s.length,o=0;odiv{line-height:22px;padding-top:7px;margin-bottom:20px;font-size:14px}.layui-m-layerbtn{display:box;display:-moz-box;display:-webkit-box;width:100%;height:50px;line-height:50px;font-size:0;border-top:1px solid #D0D0D0;background-color:#F2F2F2}.layui-m-layerbtn span{display:block;-moz-box-flex:1;box-flex:1;-webkit-box-flex:1;font-size:14px;cursor:pointer}.layui-m-layerbtn span[yes]{color:#40AFFE}.layui-m-layerbtn span[no]{border-right:1px solid #D0D0D0;border-radius:0 0 0 5px}.layui-m-layerbtn span:active{background-color:#F6F6F6}.layui-m-layerend{position:absolute;right:7px;top:10px;width:30px;height:30px;border:0;font-weight:400;background:0 0;cursor:pointer;-webkit-appearance:none;font-size:30px}.layui-m-layerend::after,.layui-m-layerend::before{position:absolute;left:5px;top:15px;content:'';width:18px;height:1px;background-color:#999;transform:rotate(45deg);-webkit-transform:rotate(45deg);border-radius:3px}.layui-m-layerend::after{transform:rotate(-45deg);-webkit-transform:rotate(-45deg)}body .layui-m-layer .layui-m-layer-footer{position:fixed;width:95%;max-width:100%;margin:0 auto;left:0;right:0;bottom:10px;background:0 0}.layui-m-layer-footer .layui-m-layercont{padding:20px;border-radius:5px 5px 0 0;background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn{display:block;height:auto;background:0 0;border-top:none}.layui-m-layer-footer .layui-m-layerbtn span{background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn span[no]{color:#FD482C;border-top:1px solid #c2c2c2;border-radius:0 0 5px 5px}.layui-m-layer-footer .layui-m-layerbtn span[yes]{margin-top:10px;border-radius:5px}body .layui-m-layer .layui-m-layer-msg{width:auto;max-width:90%;margin:0 auto;bottom:-150px;background-color:rgba(0,0,0,.7);color:#fff}.layui-m-layer-msg .layui-m-layercont{padding:10px 20px} \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/default/icon-ext.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/default/icon-ext.png new file mode 100644 index 0000000..bbbb669 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/default/icon-ext.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/default/icon.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/default/icon.png new file mode 100644 index 0000000..3e17da8 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/default/icon.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/default/layer.css b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/default/layer.css new file mode 100644 index 0000000..b88c0c7 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/default/layer.css @@ -0,0 +1 @@ +.layui-layer-imgbar,.layui-layer-imgtit a,.layui-layer-tab .layui-layer-title span,.layui-layer-title{text-overflow:ellipsis;white-space:nowrap}*html{background-image:url(about:blank);background-attachment:fixed}html #layuicss-skinlayercss{display:none;position:absolute;width:1989px}.layui-layer,.layui-layer-shade{position:fixed;_position:absolute;pointer-events:auto}.layui-layer-shade{top:0;left:0;width:100%;height:100%;_height:expression(document.body.offsetHeight+"px")}.layui-layer{-webkit-overflow-scrolling:touch;top:150px;left:0;margin:0;padding:0;background-color:#fff;-webkit-background-clip:content;box-shadow:1px 1px 50px rgba(0,0,0,.3)}.layui-layer-close{position:absolute}.layui-layer-content{position:relative}.layui-layer-border{border:1px solid #B2B2B2;border:1px solid rgba(0,0,0,.1);box-shadow:1px 1px 5px rgba(0,0,0,.2)}.layui-layer-load{background:url(loading-1.gif) center center no-repeat #eee}.layui-layer-ico{background:url(icon.png) no-repeat}.layui-layer-btn a,.layui-layer-dialog .layui-layer-ico,.layui-layer-setwin a{display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-move{display:none;position:fixed;*position:absolute;left:0;top:0;width:100%;height:100%;cursor:move;opacity:0;filter:alpha(opacity=0);background-color:#fff;z-index:2147483647}.layui-layer-resize{position:absolute;width:15px;height:15px;right:0;bottom:0;cursor:se-resize}.layui-layer{border-radius:2px;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.3s;animation-duration:.3s}@-webkit-keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.5);-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-01{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.layer-anim-02{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-03{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);-ms-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}.layer-anim-04{-webkit-animation-name:rollIn;animation-name:rollIn}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layer-anim-06{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes bounceOut{100%{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceOut{100%{opacity:0;-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);-ms-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-close{-webkit-animation-name:bounceOut;animation-name:bounceOut;-webkit-animation-duration:.2s;animation-duration:.2s}.layui-layer-title{padding:0 80px 0 20px;height:42px;line-height:42px;border-bottom:1px solid #eee;font-size:14px;color:#333;overflow:hidden;background-color:#F8F8F8;border-radius:2px 2px 0 0}.layui-layer-setwin{position:absolute;right:15px;*right:0;top:15px;font-size:0;line-height:initial}.layui-layer-setwin a{position:relative;width:16px;height:16px;margin-left:10px;font-size:12px;_overflow:hidden}.layui-layer-setwin .layui-layer-min cite{position:absolute;width:14px;height:2px;left:0;top:50%;margin-top:-1px;background-color:#2E2D3C;cursor:pointer;_overflow:hidden}.layui-layer-setwin .layui-layer-min:hover cite{background-color:#2D93CA}.layui-layer-setwin .layui-layer-max{background-position:-32px -40px}.layui-layer-setwin .layui-layer-max:hover{background-position:-16px -40px}.layui-layer-setwin .layui-layer-maxmin{background-position:-65px -40px}.layui-layer-setwin .layui-layer-maxmin:hover{background-position:-49px -40px}.layui-layer-setwin .layui-layer-close1{background-position:0 -40px;cursor:pointer}.layui-layer-setwin .layui-layer-close1:hover{opacity:.7}.layui-layer-setwin .layui-layer-close2{position:absolute;right:-28px;top:-28px;width:30px;height:30px;margin-left:0;background-position:-149px -31px;*right:-18px;_display:none}.layui-layer-setwin .layui-layer-close2:hover{background-position:-180px -31px}.layui-layer-btn{text-align:right;padding:0 10px 12px;pointer-events:auto;user-select:none;-webkit-user-select:none}.layui-layer-btn a{height:28px;line-height:28px;margin:0 6px;padding:0 15px;border:1px solid #dedede;background-color:#f1f1f1;color:#333;border-radius:2px;font-weight:400;cursor:pointer;text-decoration:none}.layui-layer-btn a:hover{opacity:.9;text-decoration:none}.layui-layer-btn a:active{opacity:.8}.layui-layer-btn .layui-layer-btn0{border-color:#4898d5;background-color:#2e8ded;color:#fff}.layui-layer-btn-l{text-align:left}.layui-layer-btn-c{text-align:center}.layui-layer-dialog{min-width:260px}.layui-layer-dialog .layui-layer-content{position:relative;padding:20px;line-height:24px;word-break:break-all;overflow:hidden;font-size:14px;overflow-x:hidden;overflow-y:auto}.layui-layer-dialog .layui-layer-content .layui-layer-ico{position:absolute;top:16px;left:15px;_left:-40px;width:30px;height:30px}.layui-layer-ico1{background-position:-30px 0}.layui-layer-ico2{background-position:-60px 0}.layui-layer-ico3{background-position:-90px 0}.layui-layer-ico4{background-position:-120px 0}.layui-layer-ico5{background-position:-150px 0}.layui-layer-ico6{background-position:-180px 0}.layui-layer-rim{border:6px solid #8D8D8D;border:6px solid rgba(0,0,0,.3);border-radius:5px;box-shadow:none}.layui-layer-msg{min-width:180px;border:1px solid #D3D4D3;box-shadow:none}.layui-layer-hui{min-width:100px;background-color:#000;filter:alpha(opacity=60);background-color:rgba(0,0,0,.6);color:#fff;border:none}.layui-layer-hui .layui-layer-content{padding:12px 25px;text-align:center}.layui-layer-dialog .layui-layer-padding{padding:20px 20px 20px 55px;text-align:left}.layui-layer-page .layui-layer-content{position:relative;overflow:auto}.layui-layer-iframe .layui-layer-btn,.layui-layer-page .layui-layer-btn{padding-top:10px}.layui-layer-nobg{background:0 0}.layui-layer-iframe iframe{display:block;width:100%}.layui-layer-loading{border-radius:100%;background:0 0;box-shadow:none;border:none}.layui-layer-loading .layui-layer-content{width:60px;height:24px;background:url(loading-0.gif) no-repeat}.layui-layer-loading .layui-layer-loading1{width:37px;height:37px;background:url(loading-1.gif) no-repeat}.layui-layer-ico16,.layui-layer-loading .layui-layer-loading2{width:32px;height:32px;background:url(loading-2.gif) no-repeat}.layui-layer-tips{background:0 0;box-shadow:none;border:none}.layui-layer-tips .layui-layer-content{position:relative;line-height:22px;min-width:12px;padding:5px 10px;font-size:12px;_float:left;border-radius:2px;box-shadow:1px 1px 3px rgba(0,0,0,.2);background-color:#000;color:#fff}.layui-layer-tips .layui-layer-close{right:-2px;top:-1px}.layui-layer-tips i.layui-layer-TipsG{position:absolute;width:0;height:0;border-width:8px;border-color:transparent;border-style:dashed;*overflow:hidden}.layui-layer-tips i.layui-layer-TipsB,.layui-layer-tips i.layui-layer-TipsT{left:5px;border-right-style:solid;border-right-color:#000}.layui-layer-tips i.layui-layer-TipsT{bottom:-8px}.layui-layer-tips i.layui-layer-TipsB{top:-8px}.layui-layer-tips i.layui-layer-TipsL,.layui-layer-tips i.layui-layer-TipsR{top:1px;border-bottom-style:solid;border-bottom-color:#000}.layui-layer-tips i.layui-layer-TipsR{left:-8px}.layui-layer-tips i.layui-layer-TipsL{right:-8px}.layui-layer-lan[type=dialog]{min-width:280px}.layui-layer-lan .layui-layer-title{background:#4476A7;color:#fff;border:none}.layui-layer-lan .layui-layer-btn{padding:10px;text-align:right;border-top:1px solid #E9E7E7}.layui-layer-lan .layui-layer-btn a{background:#BBB5B5;border:none}.layui-layer-lan .layui-layer-btn .layui-layer-btn1{background:#C9C5C5}.layui-layer-molv .layui-layer-title{background:#009f95;color:#fff;border:none}.layui-layer-molv .layui-layer-btn a{background:#009f95}.layui-layer-molv .layui-layer-btn .layui-layer-btn1{background:#92B8B1}.layui-layer-iconext{background:url(icon-ext.png) no-repeat}.layui-layer-prompt .layui-layer-input{display:block;width:220px;height:30px;margin:0 auto;line-height:30px;padding:0 5px;border:1px solid #ccc;box-shadow:1px 1px 5px rgba(0,0,0,.1) inset;color:#333}.layui-layer-prompt textarea.layui-layer-input{width:300px;height:100px;line-height:20px}.layui-layer-prompt .layui-layer-content{padding:20px}.layui-layer-prompt .layui-layer-btn{padding-top:0}.layui-layer-tab{box-shadow:1px 1px 50px rgba(0,0,0,.4)}.layui-layer-tab .layui-layer-title{padding-left:0;border-bottom:1px solid #ccc;background-color:#eee;overflow:visible}.layui-layer-tab .layui-layer-title span{position:relative;float:left;min-width:80px;max-width:260px;padding:0 20px;text-align:center;cursor:default;overflow:hidden}.layui-layer-tab .layui-layer-title span.layui-layer-tabnow{height:43px;border-left:1px solid #ccc;border-right:1px solid #ccc;background-color:#fff;z-index:10}.layui-layer-tab .layui-layer-title span:first-child{border-left:none}.layui-layer-tabmain{line-height:24px;clear:both}.layui-layer-tabmain .layui-layer-tabli{display:none}.layui-layer-tabmain .layui-layer-tabli.xubox_tab_layer{display:block}.xubox_tabclose{position:absolute;right:10px;top:5px;cursor:pointer}.layui-layer-photos{-webkit-animation-duration:1s;animation-duration:1s}.layui-layer-photos .layui-layer-content{overflow:hidden;text-align:center}.layui-layer-photos .layui-layer-phimg img{position:relative;width:100%;display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-imgbar,.layui-layer-imguide{display:none}.layui-layer-imgnext,.layui-layer-imgprev{position:absolute;top:50%;width:27px;_width:44px;height:44px;margin-top:-22px;outline:0;blr:expression(this.onFocus=this.blur())}.layui-layer-imgprev{left:10px;background-position:-5px -5px;_background-position:-70px -5px}.layui-layer-imgprev:hover{background-position:-33px -5px;_background-position:-120px -5px}.layui-layer-imgnext{right:10px;_right:8px;background-position:-5px -50px;_background-position:-70px -50px}.layui-layer-imgnext:hover{background-position:-33px -50px;_background-position:-120px -50px}.layui-layer-imgbar{position:absolute;left:0;bottom:0;width:100%;height:32px;line-height:32px;background-color:rgba(0,0,0,.8);background-color:#000\9;filter:Alpha(opacity=80);color:#fff;overflow:hidden;font-size:0}.layui-layer-imgtit *{display:inline-block;*display:inline;*zoom:1;vertical-align:top;font-size:12px}.layui-layer-imgtit a{max-width:65%;overflow:hidden;color:#fff}.layui-layer-imgtit a:hover{color:#fff;text-decoration:underline}.layui-layer-imgtit em{padding-left:10px;font-style:normal}@media screen and (max-width:1100px){.layui-layer-iframe{overflow-y:auto;-webkit-overflow-scrolling:touch}} \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/default/loading-0.gif b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/default/loading-0.gif new file mode 100644 index 0000000..6f3c953 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/default/loading-0.gif differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/default/loading-1.gif b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/default/loading-1.gif new file mode 100644 index 0000000..db3a483 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/default/loading-1.gif differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/default/loading-2.gif b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/default/loading-2.gif new file mode 100644 index 0000000..5bb90fd Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/default/loading-2.gif differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/moon/default.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/moon/default.png new file mode 100644 index 0000000..77dfaf3 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/moon/default.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/moon/style.css b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/moon/style.css new file mode 100644 index 0000000..027dd1e --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/layer/skin/moon/style.css @@ -0,0 +1 @@ +html #layui_layer_skinmoonstylecss{display:none;position:absolute;width:1989px}body .layer-ext-moon[type=dialog]{min-width:320px}body .layer-ext-moon-msg[type=dialog]{min-width:200px}body .layer-ext-moon .layui-layer-title{background:#f6f6f6;color:#212a31;font-size:16px;font-weight:700;height:46px;line-height:46px;border-bottom:1px solid #D5D5D5}body .layer-ext-moon .layui-layer-content .layui-layer-ico{height:32px;width:32px;top:18.5px}body .layer-ext-moon .layui-layer-ico0{background:url(default.png) -96px 0 no-repeat}body .layer-ext-moon .layui-layer-ico1{background:url(default.png) -224px 0 no-repeat}body .layer-ext-moon .layui-layer-ico2{background:url(default.png) -192px 0 no-repeat}body .layer-ext-moon .layui-layer-ico3{background:url(default.png) -160px 0 no-repeat}body .layer-ext-moon .layui-layer-ico4{background:url(default.png) -320px 0 no-repeat}body .layer-ext-moon .layui-layer-ico5{background:url(default.png) -288px 0 no-repeat}body .layer-ext-moon .layui-layer-ico6{background:url(default.png) -256px 0}body .layer-ext-moon .layui-layer-ico7{background:url(default.png) -128px 0 no-repeat}body .layer-ext-moon .layui-layer-setwin{top:15px;right:15px}body .layer-ext-moon .layui-layer-setwin a{width:16px;height:16px}body .layer-ext-moon .layui-layer-setwin .layui-layer-min cite:hover{background-color:#56abe4}body .layer-ext-moon .layui-layer-setwin .layui-layer-max{background:url(default.png) -80px 0 no-repeat}body .layer-ext-moon .layui-layer-setwin .layui-layer-max:hover{background:url(default.png) -64px 0 no-repeat}body .layer-ext-moon .layui-layer-setwin .layui-layer-maxmin{background:url(default.png) -32px 0 no-repeat}body .layer-ext-moon .layui-layer-setwin .layui-layer-maxmin:hover{background:url(default.png) -16px 0 no-repeat}body .layer-ext-moon .layui-layer-setwin .layui-layer-close1,body .layer-ext-moon .layui-layer-setwin .layui-layer-close2{background:url(default.png)}body .layer-ext-moon .layui-layer-setwin .layui-layer-close1:hover,body .layer-ext-moon .layui-layer-setwin .layui-layer-close2:hover{background:url(default.png) -48px 0}body .layer-ext-moon .layui-layer-padding{padding-top:24px}body .layer-ext-moon .layui-layer-btn{text-align:center;padding-top:15px;padding-bottom:15px;background:#f0f4f7;border-top:1px #c7c7c7 solid}body .layer-ext-moon .layui-layer-btn a{font-size:12px;font-weight:400;margin:0 7px;padding:6px 20px;color:#fff;border:1px solid #0064b6;background:no-repeat #0071ce;border-radius:3px;display:inline-block;height:20px;line-height:20px;text-align:center;vertical-align:middle;text-decoration:none;outline:0}body .layer-ext-moon .layui-layer-btn .layui-layer-btn0{background:#0071ce}body .layer-ext-moon .layui-layer-btn .layui-layer-btn1{background:#fff;color:#404a58;border:1px solid #c0c4cd;border-radius:3px}body .layer-ext-moon .layui-layer-btn .layui-layer-btn2{background:#f60;color:#fff;border:1px solid #f60;border-radius:3px}body .layer-ext-moon .layui-layer-btn .layui-layer-btn3{background:red;color:#fff;border:1px solid red;border-radius:3px}body .layer-ext-moon .layui-layer-title span.layui-layer-tabnow{height:47px} \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/img/collapse.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/img/collapse.png new file mode 100644 index 0000000..76577a5 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/img/collapse.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/img/expand.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/img/expand.png new file mode 100644 index 0000000..cfb42a4 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/img/expand.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/img/file.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/img/file.png new file mode 100644 index 0000000..813f712 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/img/file.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/img/folder.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/img/folder.png new file mode 100644 index 0000000..784e8fa Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/img/folder.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/jquery.treegrid.bootstrap3.js b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/jquery.treegrid.bootstrap3.js new file mode 100644 index 0000000..ac4a835 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/jquery.treegrid.bootstrap3.js @@ -0,0 +1,4 @@ +$.extend($.fn.treegrid.defaults, { + expanderExpandedClass: 'glyphicon glyphicon-chevron-down', + expanderCollapsedClass: 'glyphicon glyphicon-chevron-right' +}); diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/jquery.treegrid.css b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/jquery.treegrid.css new file mode 100644 index 0000000..2487166 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/jquery.treegrid.css @@ -0,0 +1,17 @@ +.treegrid-indent {width:16px; height: 16px; display: inline-block; position: relative;} + +.treegrid-expander {width:16px; height: 16px; display: inline-block; position: relative; cursor: pointer;} + +.treegrid-expander-expanded{background-image: url(img/collapse.png); } +.treegrid-expander-collapsed{background-image: url(img/expand.png);} +.treegrid-selected{background: #f5f5f5 !important;} +.treegrid-table{border:0 !important;margin-bottom:0} +.treegrid-table tbody {display:block;height:auto;overflow-y:auto;} +.treegrid-table thead, .treegrid-table tbody tr {display:table;width:100%;table-layout:fixed;} +.treegrid-thead th{line-height:40px;border: 0 !important;background:#fff !important;border-radius: 4px;border-left:1px solid #e7eaec !important;border-bottom:2px solid #e7eaec !important;text-align: center;} +.treegrid-thead tr :first-child{border-left:0 !important} +.treegrid-tbody td{border: 0 !important;border-left:1px solid #e7eaec !important;border-bottom:1px solid #e7eaec !important;overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis;} +.treegrid-tbody tr :first-child{border-left:0 !important} + diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/jquery.treegrid.extension.js b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/jquery.treegrid.extension.js new file mode 100644 index 0000000..6d248e5 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/jquery.treegrid.extension.js @@ -0,0 +1,254 @@ +(function($) { + "use strict"; + + $.fn.bootstrapTreeTable = function(options, param) { + // 如果是调用方法 + if (typeof options == 'string') { + return $.fn.bootstrapTreeTable.methods[options](this, param); + } + + // 如果是初始化组件 + options = $.extend({}, $.fn.bootstrapTreeTable.defaults, options || {}); + // 是否有radio或checkbox + var hasSelectItem = false; + var target = $(this); + // 在外层包装一下div,样式用的bootstrap-table的 + var _main_div = $("
"); + target.before(_main_div); + _main_div.append(target); + target.addClass("table table-hover treegrid-table table-bordered"); + if (options.striped) { + target.addClass('table-striped'); + } + // 工具条在外层包装一下div,样式用的bootstrap-table的 + if(options.toolbar){ + var _tool_div = $("
"); + var _tool_left_div = $("
"); + _tool_left_div.append($(options.toolbar)); + _tool_div.append(_tool_left_div); + _main_div.before(_tool_div); + } + // 得到根节点 + target.getRootNodes = function(data) { + // 指定Root节点值 + var _root = options.rootCodeValue?options.rootCodeValue:null + var result = []; + $.each(data, function(index, item) { + // 这里兼容几种常见Root节点写法 + // 默认的几种判断 + var _defaultRootFlag = item[options.parentCode] == '0' + || item[options.parentCode] == 0 + || item[options.parentCode] == null + || item[options.parentCode] == ''; + if (!item[options.parentCode] || (_root?(item[options.parentCode] == options.rootCodeValue):_defaultRootFlag)){ + result.push(item); + } + // 添加一个默认属性,用来判断当前节点有没有被显示 + item.isShow = false; + }); + return result; + }; + var j = 0; + // 递归获取子节点并且设置子节点 + target.getChildNodes = function(data, parentNode, parentIndex, tbody) { + $.each(data, function(i, item) { + if (item[options.parentCode] == parentNode[options.code]) { + var tr = $(''); + var nowParentIndex = (parentIndex + (j++) + 1); + tr.addClass('treegrid-' + nowParentIndex); + tr.addClass('treegrid-parent-' + parentIndex); + target.renderRow(tr,item); + item.isShow = true; + tbody.append(tr); + target.getChildNodes(data, item, nowParentIndex, tbody) + + } + }); + }; + // 绘制行 + target.renderRow = function(tr,item){ + $.each(options.columns, function(index, column) { + // 判断有没有选择列 + if(index==0&&column.field=='selectItem'){ + hasSelectItem = true; + var td = $(''); + if(column.radio){ + var _ipt = $(''); + td.append(_ipt); + } + if(column.checkbox){ + var _ipt = $(''); + td.append(_ipt); + } + tr.append(td); + }else{ + var td = $(''); + // 增加formatter渲染 + if (column.formatter) { + td.html(column.formatter.call(this, item, index)); + } else { + td.text(item[column.field]); + } + tr.append(td); + } + }); + } + // 加载数据 + target.load = function(parms){ + // 加载数据前先清空 + target.html(""); + // 构造表头 + var thr = $(''); + $.each(options.columns, function(i, item) { + var th = null; + // 判断有没有选择列 + if(i==0&&item.field=='selectItem'){ + hasSelectItem = true; + th = $(''); + }else{ + th = $(''); + } + th.text(item.title); + thr.append(th); + }); + var thead = $(''); + thead.append(thr); + target.append(thead); + // 构造表体 + var tbody = $(''); + target.append(tbody); + // 添加加载loading + var _loading = '
正在努力地加载数据中,请稍候……
' + tbody.html(_loading); + // 默认高度 + if(options.height){ + tbody.css("height",options.height); + } + $.ajax({ + type : options.type, + url : options.url, + data : parms?parms:options.ajaxParams, + dataType : "JSON", + success : function(data, textStatus, jqXHR) { + // 加载完数据先清空 + tbody.html(""); + if(!data||data.length<=0){ + var _empty = '
没有记录
' + tbody.html(_empty); + return; + } + var rootNode = target.getRootNodes(data); + $.each(rootNode, function(i, item) { + var tr = $(''); + tr.addClass('treegrid-' + (j + "_" + i)); + target.renderRow(tr,item); + item.isShow = true; + tbody.append(tr); + target.getChildNodes(data, item, (j + "_" + i), tbody); + }); + // 下边的操作主要是为了查询时让一些没有根节点的节点显示 + $.each(data, function(i, item) { + if(!item.isShow){ + var tr = $(''); + tr.addClass('treegrid-' + (j + "_" + i)); + target.renderRow(tr,item); + tbody.append(tr); + } + }); + target.append(tbody); + // 初始化treegrid + target.treegrid({ + treeColumn: options.expandColumn?options.expandColumn:(hasSelectItem?1:0),//如果有radio或checkbox默认第二列层级显示,当前是在用户未设置的提前下 + expanderExpandedClass : options.expanderExpandedClass, + expanderCollapsedClass : options.expanderCollapsedClass + }); + if (!options.expandAll) { + target.treegrid('collapseAll'); + } + //动态设置表头宽度 + //thead.css("width", tbody.children(":first").css("width")); + // 行点击选中事件 + target.find("tbody").find("tr").click(function(){ + if(hasSelectItem){ + var _ipt = $(this).find("input[name='select_item']"); + if(_ipt.attr("type")=="radio"){ + _ipt.prop('checked',true); + target.find("tbody").find("tr").removeClass("treegrid-selected"); + $(this).addClass("treegrid-selected"); + }else{ + if(_ipt.prop('checked')){ + _ipt.prop('checked',false); + $(this).removeClass("treegrid-selected"); + }else{ + _ipt.prop('checked',true); + $(this).addClass("treegrid-selected"); + } + } + } + }); + }, + error:function(xhr,textStatus){ + var _errorMsg = '
'+xhr.responseText+'
' + tbody.html(_errorMsg); + debugger; + }, + }); + } + if (options.url) { + target.load(); + } else { + // 也可以通过defaults里面的data属性通过传递一个数据集合进来对组件进行初始化....有兴趣可以自己实现,思路和上述类似 + } + + return target; + }; + + // 组件方法封装........ + $.fn.bootstrapTreeTable.methods = { + // 返回选中记录的id(返回的id由配置中的id属性指定) + // 为了兼容bootstrap-table的写法,统一返回数组,这里只返回了指定的id + getSelections : function(target, data) { + // 所有被选中的记录input + var _ipt = target.find("tbody").find("tr").find("input[name='select_item']:checked"); + var chk_value =[]; + // 如果是radio + if(_ipt.attr("type")=="radio"){ + chk_value.push({id:_ipt.val()}); + }else{ + _ipt.each(function(_i,_item){ + chk_value.push({id:$(_item).val()}); + }); + } + return chk_value; + }, + // 刷新记录 + refresh : function(target, parms) { + if(parms){ + target.load(parms); + }else{ + target.load(); + } + }, + // 组件的其他方法也可以进行类似封装........ + }; + + $.fn.bootstrapTreeTable.defaults = { + id : 'menuId',// 选取记录返回的值 + code : 'menuId',// 用于设置父子关系 + parentCode : 'parentId',// 用于设置父子关系 + rootCodeValue: null,//设置根节点code值----可指定根节点,默认为null,"",0,"0" + data : [], // 构造table的数据集合 + type : "GET", // 请求数据的ajax类型 + url : null, // 请求数据的ajax的url + ajaxParams : {}, // 请求数据的ajax的data属性 + expandColumn : null,// 在哪一列上面显示展开按钮 + expandAll : true, // 是否全部展开 + striped : false, // 是否各行渐变色 + columns : [], + toolbar: null,//顶部工具条 + height: 0, + expanderExpandedClass : 'glyphicon glyphicon-chevron-down',// 展开的按钮的图标 + expanderCollapsedClass : 'glyphicon glyphicon-chevron-right'// 缩起的按钮的图标 + + }; +})(jQuery); \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/jquery.treegrid.min.js b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/jquery.treegrid.min.js new file mode 100644 index 0000000..7b7566f --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/jquery.treegrid.min.js @@ -0,0 +1,2 @@ +/*! jquery-treegrid 0.3.0 */ +!function(a){var b={initTree:function(b){var c=a.extend({},this.treegrid.defaults,b);return this.each(function(){var b=a(this);b.treegrid("setTreeContainer",a(this)),b.treegrid("setSettings",c),c.getRootNodes.apply(this,[a(this)]).treegrid("initNode",c),b.treegrid("getRootNodes").treegrid("render")})},initNode:function(b){return this.each(function(){var c=a(this);c.treegrid("setTreeContainer",b.getTreeGridContainer.apply(this)),c.treegrid("getChildNodes").treegrid("initNode",b),c.treegrid("initExpander").treegrid("initIndent").treegrid("initEvents").treegrid("initState").treegrid("initChangeEvent").treegrid("initSettingsEvents")})},initChangeEvent:function(){var b=a(this);return b.on("change",function(){var b=a(this);b.treegrid("render"),b.treegrid("getSetting","saveState")&&b.treegrid("saveState")}),b},initEvents:function(){var b=a(this);return b.on("collapse",function(){var b=a(this);b.removeClass("treegrid-expanded"),b.addClass("treegrid-collapsed")}),b.on("expand",function(){var b=a(this);b.removeClass("treegrid-collapsed"),b.addClass("treegrid-expanded")}),b},initSettingsEvents:function(){var b=a(this);return b.on("change",function(){var b=a(this);"function"==typeof b.treegrid("getSetting","onChange")&&b.treegrid("getSetting","onChange").apply(b)}),b.on("collapse",function(){var b=a(this);"function"==typeof b.treegrid("getSetting","onCollapse")&&b.treegrid("getSetting","onCollapse").apply(b)}),b.on("expand",function(){var b=a(this);"function"==typeof b.treegrid("getSetting","onExpand")&&b.treegrid("getSetting","onExpand").apply(b)}),b},initExpander:function(){var b=a(this),c=b.find("td").get(b.treegrid("getSetting","treeColumn")),d=b.treegrid("getSetting","expanderTemplate"),e=b.treegrid("getSetting","getExpander").apply(this);return e&&e.remove(),a(d).prependTo(c).click(function(){a(a(this).closest("tr")).treegrid("toggle")}),b},initIndent:function(){var b=a(this);b.find(".treegrid-indent").remove();for(var c=b.treegrid("getSetting","indentTemplate"),d=b.find(".treegrid-expander"),e=b.treegrid("getDepth"),f=0;e>f;f++)a(c).insertBefore(d);return b},initState:function(){var b=a(this);return b.treegrid(b.treegrid("getSetting","saveState")&&!b.treegrid("isFirstInit")?"restoreState":"expanded"===b.treegrid("getSetting","initialState")?"expand":"collapse"),b},isFirstInit:function(){var b=a(this).treegrid("getTreeContainer");return void 0===b.data("first_init")&&b.data("first_init",void 0===a.cookie(b.treegrid("getSetting","saveStateName"))),b.data("first_init")},saveState:function(){var b=a(this);if("cookie"===b.treegrid("getSetting","saveStateMethod")){var c=a.cookie(b.treegrid("getSetting","saveStateName"))||"",d=""===c?[]:c.split(","),e=b.treegrid("getNodeId");b.treegrid("isExpanded")?-1===a.inArray(e,d)&&d.push(e):b.treegrid("isCollapsed")&&-1!==a.inArray(e,d)&&d.splice(a.inArray(e,d),1),a.cookie(b.treegrid("getSetting","saveStateName"),d.join(","))}return b},restoreState:function(){var b=a(this);if("cookie"===b.treegrid("getSetting","saveStateMethod")){var c=a.cookie(b.treegrid("getSetting","saveStateName")).split(",");b.treegrid(-1!==a.inArray(b.treegrid("getNodeId"),c)?"expand":"collapse")}return b},getSetting:function(b){return a(this).treegrid("getTreeContainer")?a(this).treegrid("getTreeContainer").data("settings")[b]:null},setSettings:function(b){a(this).treegrid("getTreeContainer").data("settings",b)},getTreeContainer:function(){return a(this).data("treegrid")},setTreeContainer:function(b){return a(this).data("treegrid",b)},getRootNodes:function(){return a(this).treegrid("getSetting","getRootNodes").apply(this,[a(this).treegrid("getTreeContainer")])},getAllNodes:function(){return a(this).treegrid("getSetting","getAllNodes").apply(this,[a(this).treegrid("getTreeContainer")])},isNode:function(){return null!==a(this).treegrid("getNodeId")},getNodeId:function(){return null===a(this).treegrid("getSetting","getNodeId")?null:a(this).treegrid("getSetting","getNodeId").apply(this)},getParentNodeId:function(){return a(this).treegrid("getSetting","getParentNodeId").apply(this)},getParentNode:function(){return null===a(this).treegrid("getParentNodeId")?null:a(this).treegrid("getSetting","getNodeById").apply(this,[a(this).treegrid("getParentNodeId"),a(this).treegrid("getTreeContainer")])},getChildNodes:function(){return a(this).treegrid("getSetting","getChildNodes").apply(this,[a(this).treegrid("getNodeId"),a(this).treegrid("getTreeContainer")])},getDepth:function(){return null===a(this).treegrid("getParentNode")?0:a(this).treegrid("getParentNode").treegrid("getDepth")+1},isRoot:function(){return 0===a(this).treegrid("getDepth")},isLeaf:function(){return 0===a(this).treegrid("getChildNodes").length},isLast:function(){if(a(this).treegrid("isNode")){var b=a(this).treegrid("getParentNode");if(null===b){if(a(this).treegrid("getNodeId")===a(this).treegrid("getRootNodes").last().treegrid("getNodeId"))return!0}else if(a(this).treegrid("getNodeId")===b.treegrid("getChildNodes").last().treegrid("getNodeId"))return!0}return!1},isFirst:function(){if(a(this).treegrid("isNode")){var b=a(this).treegrid("getParentNode");if(null===b){if(a(this).treegrid("getNodeId")===a(this).treegrid("getRootNodes").first().treegrid("getNodeId"))return!0}else if(a(this).treegrid("getNodeId")===b.treegrid("getChildNodes").first().treegrid("getNodeId"))return!0}return!1},isExpanded:function(){return a(this).hasClass("treegrid-expanded")},isCollapsed:function(){return a(this).hasClass("treegrid-collapsed")},isOneOfParentsCollapsed:function(){var b=a(this);return b.treegrid("isRoot")?!1:b.treegrid("getParentNode").treegrid("isCollapsed")?!0:b.treegrid("getParentNode").treegrid("isOneOfParentsCollapsed")},expand:function(){return this.treegrid("isLeaf")||this.treegrid("isExpanded")?this:(this.trigger("expand"),this.trigger("change"),this)},expandAll:function(){var b=a(this);return b.treegrid("getRootNodes").treegrid("expandRecursive"),b},expandRecursive:function(){return a(this).each(function(){var b=a(this);b.treegrid("expand"),b.treegrid("isLeaf")||b.treegrid("getChildNodes").treegrid("expandRecursive")})},collapse:function(){return a(this).each(function(){var b=a(this);b.treegrid("isLeaf")||b.treegrid("isCollapsed")||(b.trigger("collapse"),b.trigger("change"))})},collapseAll:function(){var b=a(this);return b.treegrid("getRootNodes").treegrid("collapseRecursive"),b},collapseRecursive:function(){return a(this).each(function(){var b=a(this);b.treegrid("collapse"),b.treegrid("isLeaf")||b.treegrid("getChildNodes").treegrid("collapseRecursive")})},toggle:function(){var b=a(this);return b.treegrid(b.treegrid("isExpanded")?"collapse":"expand"),b},render:function(){return a(this).each(function(){var b=a(this);b.treegrid("isOneOfParentsCollapsed")?b.hide():b.show(),b.treegrid("isLeaf")||(b.treegrid("renderExpander"),b.treegrid("getChildNodes").treegrid("render"))})},renderExpander:function(){return a(this).each(function(){var b=a(this),c=b.treegrid("getSetting","getExpander").apply(this);c?b.treegrid("isCollapsed")?(c.removeClass(b.treegrid("getSetting","expanderExpandedClass")),c.addClass(b.treegrid("getSetting","expanderCollapsedClass"))):(c.removeClass(b.treegrid("getSetting","expanderCollapsedClass")),c.addClass(b.treegrid("getSetting","expanderExpandedClass"))):(b.treegrid("initExpander"),b.treegrid("renderExpander"))})}};a.fn.treegrid=function(c){return b[c]?b[c].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof c&&c?void a.error("Method with name "+c+" does not exists for jQuery.treegrid"):b.initTree.apply(this,arguments)},a.fn.treegrid.defaults={initialState:"expanded",saveState:!1,saveStateMethod:"cookie",saveStateName:"tree-grid-state",expanderTemplate:'',indentTemplate:'',expanderExpandedClass:"treegrid-expander-expanded",expanderCollapsedClass:"treegrid-expander-collapsed",treeColumn:0,getExpander:function(){return a(this).find(".treegrid-expander")},getNodeId:function(){var b=/treegrid-([A-Za-z0-9_-]+)/;return b.test(a(this).attr("class"))?b.exec(a(this).attr("class"))[1]:null},getParentNodeId:function(){var b=/treegrid-parent-([A-Za-z0-9_-]+)/;return b.test(a(this).attr("class"))?b.exec(a(this).attr("class"))[1]:null},getNodeById:function(a,b){var c="treegrid-"+a;return b.find("tr."+c)},getChildNodes:function(a,b){var c="treegrid-parent-"+a;return b.find("tr."+c)},getTreeGridContainer:function(){return a(this).closest("table")},getRootNodes:function(b){var c=a.grep(b.find("tr"),function(b){var c=a(b).attr("class"),d=/treegrid-([A-Za-z0-9_-]+)/,e=/treegrid-parent-([A-Za-z0-9_-]+)/;return d.test(c)&&!e.test(c)});return a(c)},getAllNodes:function(b){var c=a.grep(b.find("tr"),function(b){var c=a(b).attr("class"),d=/treegrid-([A-Za-z0-9_-]+)/;return d.test(c)});return a(c)},onCollapse:null,onExpand:null,onChange:null}}(jQuery); \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/tree.table.js b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/tree.table.js new file mode 100644 index 0000000..a8db09f --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/treegrid/tree.table.js @@ -0,0 +1,136 @@ +/** + * 初始化 Tree Table 的封装 + * + * @author cyf + */ +(function () { + var TreeTable = function (tableId, url, columns) { + this.btInstance = null; //jquery和bootstrapTreeTable绑定的对象 + this.bstableId = tableId; + this.url = url; + this.method = "GET"; + this.columns = columns; + this.data = {};// ajax的参数 + this.expandColumn = null;// 展开显示的列 + this.id = 'menuId';// 选取记录返回的值 + this.code = 'menuId';// 用于设置父子关系 + this.parentCode = 'parentId';// 用于设置父子关系 + this.expandAll = false;// 是否默认全部展开 + this.toolbarId = tableId + "Toolbar"; + this.height = 430; + }; + + TreeTable.prototype = { + /** + * 初始化bootstrap table + */ + init: function () { + var tableId = this.bstableId; + this.btInstance = + $('#'+tableId).bootstrapTreeTable({ + id: this.id,// 选取记录返回的值 + code: this.code,// 用于设置父子关系 + parentCode: this.parentCode,// 用于设置父子关系 + rootCodeValue: this.rootCodeValue,//设置根节点code值----可指定根节点,默认为null,"",0,"0" + type: this.method, //请求数据的ajax类型 + url: this.url, //请求数据的ajax的url + ajaxParams: this.data, //请求数据的ajax的data属性 + expandColumn: this.expandColumn,//在哪一列上面显示展开按钮,从0开始 + striped: true, //是否各行渐变色 + expandAll: this.expandAll, //是否全部展开 + columns: this.columns, //列数组 + toolbar: "#" + this.toolbarId,//顶部工具条 + height: this.height, + }); + return this; + }, + + /** + * 设置在哪一列上面显示展开按钮,从0开始 + */ + setExpandColumn: function (expandColumn) { + this.expandColumn = expandColumn; + }, + /** + * 设置记录返回的id值 + */ + setIdField: function (id) { + this.id = id; + }, + /** + * 设置记录分级的字段 + */ + setCodeField: function (code) { + this.code = code; + }, + /** + * 设置记录分级的父级字段 + */ + setParentCodeField: function (parentCode) { + this.parentCode = parentCode; + }, + /** + * 设置根节点code值----可指定根节点,默认为null,"",0,"0" + */ + setRootCodeValue: function (rootCodeValue) { + this.rootCodeValue = rootCodeValue; + }, + /** + * 设置是否默认全部展开 + */ + setExpandAll: function (expandAll) { + this.expandAll = expandAll; + }, + /** + * 设置表格高度 + */ + setHeight: function (height) { + this.height = height; + }, + /** + * 设置ajax post请求时候附带的参数 + */ + set: function (key, value) { + if (typeof key == "object") { + for (var i in key) { + if (typeof i == "function") + continue; + this.data[i] = key[i]; + } + } else { + this.data[key] = (typeof value == "undefined") ? $("#" + key).val() : value; + } + return this; + }, + + /** + * 设置ajax get请求时候附带的参数 + */ + setData: function (data) { + this.data = data; + return this; + }, + + /** + * 清空ajax post请求参数 + */ + clear: function () { + this.data = {}; + return this; + }, + + /** + * 刷新表格 + */ + refresh: function (parms) { + if (typeof parms != "undefined") { + this.btInstance.bootstrapTreeTable('refresh', parms.query);// 为了兼容bootstrap-table的写法 + } else { + this.btInstance.bootstrapTreeTable('refresh'); + } + } + }; + + window.TreeTable = TreeTable; + +}()); \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/awesomeStyle/awesome.css b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/awesomeStyle/awesome.css new file mode 100644 index 0000000..c1fcf3a --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/awesomeStyle/awesome.css @@ -0,0 +1,386 @@ +/*------------------------------------- +zTree Style using fontawesome instead of images + +version: 1.1 +author: Mike King +email: mikkelking @ hotmail . com +website: http://code.google.com/p/jquerytree/ + +-------------------------------------*/ +/* Definitions ----------------------*/ +/* End of Definitions ---------------*/ +/* Imports -------------------------*/ +/* End of Imports ------------------*/ +.ztree * { + padding: 0; + margin: 0; + font-size: 12px; + font-family: Verdana, Arial, Helvetica, AppleGothic, sans-serif; + background-color: #af0000; +} +.ztree { + margin: 0; + padding: 5px; + color: #ffffff; + background-color: #af0000; +} +.ztree li { + padding: 0; + margin: 0; + list-style: none; + line-height: 17px; + text-align: left; + white-space: nowrap; + outline: 0; +} +.ztree li ul { + margin: 0px; + padding: 0 0 0 18px; +} +.ztree li a { + padding-right: 3px; + margin: 0; + cursor: pointer; + height: 17px; + color: #ffffff; + background-color: transparent; + text-decoration: none; + vertical-align: top; + display: inline-block; +} +.ztree li a input.rename { + height: 14px; + width: 80px; + padding: 0; + margin: 0; + color: #af0000; + background-color: #ffffff; + font-size: 12px; + border: 1px #585956 solid; + *border: 0px; +} +.ztree li a:hover { + text-decoration: underline; +} +.ztree li a.curSelectedNode { + padding-top: 0px; + background-color: #af4040; + color: #ffff00; + height: 17px; + opacity: 0.8; +} +.ztree li a.curSelectedNode_Edit { + padding-top: 0px; + background-color: transparent; + color: #ffff00; + height: 17px; + border: 1px #666 solid; + opacity: 0.8; +} +.ztree li a.tmpTargetNode_inner { + padding-top: 0px; + background-color: #aaa; + color: #ffff00; + height: 17px; + border: 1px #666 solid; + opacity: 0.8; + filter: alpha(opacity=80); +} +.ztree li span { + line-height: 17px; + margin-right: 2px; + background-color: transparent; +} +.ztree li span.button { + line-height: 0; + margin: 0; + padding: 0; + width: 15px; + height: 17px; + display: inline-block; + vertical-align: top; + border: 0px solid; + cursor: pointer; + outline: none; + background-color: transparent; + background-repeat: no-repeat; + background-attachment: scroll; +} +.ztree li span.button::before { + color: #ffffff; + font-family: FontAwesome; + padding-top: 10px; +} +.ztree li span.button.chk { + margin: 0px; + cursor: auto; + width: 12px; + display: inline-block; + padding-top: 10px; + padding-left: 2px; +} +.ztree li span.button.chk.checkbox_false_full::before { + content: "\f096"; +} +.ztree li span.button.chk.checkbox_false_full_focus::before { + content: "\f096"; + color: #ffff00; +} +.ztree li span.button.chk.checkbox_false_part::before { + content: "\f096"; + color: #aaaaaa; +} +.ztree li span.button.chk.checkbox_false_part_focus::before { + content: "\f096"; + color: #cad96c; +} +.ztree li span.button.chk.checkbox_false_disable::before { + content: "\f096"; + color: #808080; +} +.ztree li span.button.chk.checkbox_true_full::before { + content: "\f046"; +} +.ztree li span.button.chk.checkbox_true_full_focus::before { + content: "\f046"; +} +.ztree li span.button.chk.checkbox_true_part::before { + content: "\f14a"; +} +.ztree li span.button.chk.checkbox_true_part_focus::before { + content: "\f14a"; + color: #ffff00; +} +.ztree li span.button.chk.checkbox_true_full_focus::before { + content: "\f046"; + color: #ffff00; +} +.ztree li span.button.chk.checkbox_true_part::before { + content: "\f046"; + color: #aaaaaa; +} +.ztree li span.button.chk.checkbox_true_part_focus::before { + content: "\f046"; + color: #cad96c; +} +.ztree li span.button.chk.checkbox_true_disable::before { + content: "\f046"; + color: #808080; +} +.ztree li span.button.chk.radio_false_full::before { + content: "\f10c"; +} +.ztree li span.button.chk.radio_false_full_focus::before { + content: "\f10c"; + color: #ffff00; +} +.ztree li span.button.chk.radio_false_part::before { + content: "\f10c"; + color: #aaaaaa; +} +.ztree li span.button.chk.radio_false_part_focus::before { + content: "\f10c"; + color: #ffff00; +} +.ztree li span.button.chk.radio_false_disable::before { + content: "\f1db"; + color: #808080; +} +.ztree li span.button.chk.radio_true_full::before { + content: "\f192"; +} +.ztree li span.button.chk.radio_true_full_focus::before { + content: "\f192"; + color: #ffff00; +} +.ztree li span.button.chk.radio_true_part::before { + content: "\f192"; + color: #aaaaaa; +} +.ztree li span.button.chk.radio_true_part_focus::before { + content: "\f192"; + color: #aaaaaa; +} +.ztree li span.button.chk.radio_true_disable::before { + content: "\f1db"; + color: #808080; +} +.ztree li span.button.switch { + width: 15px; + height: 17px; +} +.ztree li span.button.root_open::before { + content: "\f078"; + padding-top: 10px; + padding-left: 2px; + display: inline-block; +} +.ztree li span.button.root_close::before { + content: "\f115"; + padding-top: 10px; + padding-left: 2px; + display: inline-block; +} +.ztree li span.button.roots_open::before { + content: "\f078"; + padding-top: 10px; + padding-left: 2px; + display: inline-block; +} +.ztree li span.button.roots_close::before { + content: "\f054"; + padding-top: 10px; + padding-left: 2px; + display: inline-block; +} +.ztree li span.button.center_open::before { + content: "\f078"; + padding-top: 10px; + padding-left: 2px; + display: inline-block; +} +.ztree li span.button.center_close::before { + content: "\f054"; + padding-top: 10px; + padding-left: 2px; + display: inline-block; +} +.ztree li span.button.bottom_open::before { + content: "\f078"; + padding-top: 10px; + padding-left: 2px; + display: inline-block; +} +.ztree li span.button.bottom_close::before { + content: "\f054"; + padding-top: 10px; + padding-left: 2px; + display: inline-block; +} +.ztree li span.button.root_docu { + background: none; +} +.ztree li span.button.roots_docu::before { + content: "\f022"; + padding-left: 2px; + display: inline-block; + color: #ffffff; +} +.ztree li span.button.center_docu::before { + padding-top: 10px; + padding-left: 2px; + display: inline-block; + color: #ffffff; +} +.ztree li span.button.bottom_docu::before { + padding-top: 10px; + padding-left: 2px; + display: inline-block; + color: #ffffff; +} +.ztree li span.button.noline_docu { + background: none; +} +.ztree li span.button.ico_open::before { + content: "\f115"; + font-family: FontAwesome; + padding-top: 10px; + padding-left: 2px; + display: inline-block; + color: #ffffff; +} +.ztree li span.button.ico_close::before { + content: "\f114"; + font-family: FontAwesome; + padding-top: 10px; + padding-left: 2px; + display: inline-block; + color: #ffffff; +} +.ztree li span.button.ico_docu::before { + content: "\f022"; + font-family: FontAwesome; + padding-top: 10px; + padding-left: 2px; + display: inline-block; + color: #ffffff; +} +.ztree li span.button.edit { + margin-left: 4px; + margin-right: -1px; + vertical-align: top; + *vertical-align: middle; + padding-top: 10px; +} +.ztree li span.button.edit::before { + content: "\f044"; + font-family: FontAwesome; +} +.ztree li span.button.remove { + margin-left: 4px; + margin-right: -1px; + vertical-align: top; + *vertical-align: middle; + padding-top: 10px; +} +.ztree li span.button.remove::before { + content: "\f1f8"; + font-family: FontAwesome; +} +.ztree li span.button.add { + margin-left: 4px; + margin-right: -1px; + vertical-align: top; + *vertical-align: middle; + padding-top: 10px; +} +.ztree li span.button.add::before { + content: "\f067"; + font-family: FontAwesome; +} +.ztree li span.button.ico_loading { + margin-right: 2px; + background: url(./img/loading.gif) no-repeat scroll 0 0 transparent; + vertical-align: top; + *vertical-align: middle; +} +ul.tmpTargetzTree { + background-color: #FFE6B0; + opacity: 0.8; + filter: alpha(opacity=80); +} +span.tmpzTreeMove_arrow { + width: 16px; + height: 17px; + display: inline-block; + padding: 0; + margin: 2px 0 0 1px; + border: 0 none; + position: absolute; + background-color: transparent; + background-attachment: scroll; +} +span.tmpzTreeMove_arrow::before { + content: "\f04b"; + font-family: FontAwesome; + color: #ffff00; +} +ul.ztree.zTreeDragUL { + margin: 0; + padding: 0; + position: absolute; + width: auto; + height: auto; + overflow: hidden; + background-color: #cfcfcf; + border: 1px #ffff00 dotted; + opacity: 0.8; + filter: alpha(opacity=80); +} +.ztreeMask { + z-index: 10000; + background-color: #cfcfcf; + opacity: 0.0; + filter: alpha(opacity=0); + position: absolute; +} diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/awesomeStyle/awesome.less b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/awesomeStyle/awesome.less new file mode 100644 index 0000000..b282d81 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/awesomeStyle/awesome.less @@ -0,0 +1,146 @@ +/*------------------------------------- +zTree Style using fontawesome instead of images + +version: 1.1 +author: Mike King +email: mikkelking @ hotmail . com +website: http://code.google.com/p/jquerytree/ + +-------------------------------------*/ + +/* Definitions ----------------------*/ +@font-size: 12px; +// Regular icon and text color is white, which suits any medium -> dark background +@color-normal: white; +// Background color +@color-bg: #af0000; +// Highlight color +@color-highlight: yellow; +// Partially selected (checkboxes, radio buttons) +@color-partial: #aaaaaa; +// Partially selected and focused (checkboxes, radio buttons) +@color-partfocus: #cad96c; +// Disabled altogether +@color-disabled: #808080; +// Editing color +@color-edit: yellow; +@w: 15px; +@h: 17px; +@pad-left: 2px; +@pad-top: 10px; +/* End of Definitions ---------------*/ + +/* Imports -------------------------*/ +@import "fa.less"; +/* End of Imports ------------------*/ + +.ztree * {padding:0; margin:0; font-size:@font-size; font-family: Verdana, Arial, Helvetica, AppleGothic, sans-serif; background-color: @color-bg;} +.ztree { + margin:0; padding:5px; color:@color-normal; background-color: @color-bg; + li { + padding:0; margin:0; list-style:none; line-height:17px; text-align:left; white-space:nowrap; outline:0; + ul { + margin: 0px; padding:0 0 0 18px; + } + ul.line { } + a {padding-right:3px; margin:0; cursor:pointer; height:@h; color:@color-normal; background-color: transparent; + text-decoration:none; vertical-align:top; display: inline-block; + input.rename {height:14px; width:80px; padding:0; margin:0; + color: @color-bg; background-color: @color-normal; + font-size:@font-size; border:1px #585956 solid; *border:0px} + } + a:hover {text-decoration:underline} + a.curSelectedNode {padding-top:0px; background-color:#af4040; color:@color-highlight; height:@h; opacity:0.8;} + a.curSelectedNode_Edit {padding-top:0px; background-color:transparent; color:@color-highlight; height:@h; border:1px #666 solid; opacity:0.8;} + a.tmpTargetNode_inner {padding-top:0px; background-color:#aaa; color:@color-highlight; height:@h; border:1px #666 solid; + opacity:0.8; filter:alpha(opacity=80)} + a.tmpTargetNode_prev {} + a.tmpTargetNode_next {} + span {line-height:@h; margin-right:2px; background-color:transparent;} + span.button {line-height:0; margin:0; padding: 0; width:@w; height:@h; display: inline-block; vertical-align:top; + border:0px solid; cursor: pointer;outline:none; + background-color:transparent; background-repeat:no-repeat; background-attachment: scroll; + + &::before{color: @color-normal; font-family: FontAwesome; padding-top:@pad-top;} + &.chk { margin:0px; cursor: auto; width: 12px; + display: inline-block;padding-top:@pad-top;padding-left:@pad-left; + + &.checkbox_false_full::before {content: @fa-square-o;} + &.checkbox_false_full_focus::before {content: @fa-square-o; color:@color-highlight;} + &.checkbox_false_part::before {content: @fa-square-o;color: @color-partial;} + &.checkbox_false_part_focus::before {content: @fa-square-o; color:@color-partfocus;} + &.checkbox_false_disable::before {content: @fa-square-o; color:@color-disabled;} + &.checkbox_true_full::before {content: @fa-check-square-o;} + &.checkbox_true_full_focus::before {content: @fa-check-square-o;} + &.checkbox_true_part::before {content: @fa-check-square;} + &.checkbox_true_part_focus::before {content: @fa-check-square; color: @color-highlight} + &.checkbox_true_full_focus::before {content: @fa-check-square-o; color: @color-highlight} + &.checkbox_true_part::before {content: @fa-check-square-o;color: @color-partial} + &.checkbox_true_part_focus::before {content: @fa-check-square-o;color: @color-partfocus;} + &.checkbox_true_disable::before {content: @fa-check-square-o;color: @color-disabled} + + &.radio_false_full::before {content: @fa-circle-o;} + &.radio_false_full_focus::before {content: @fa-circle-o;color: @color-highlight} + &.radio_false_part::before {content: @fa-circle-o;color: @color-partial} + &.radio_false_part_focus::before {content: @fa-circle-o;color: @color-highlight} + &.radio_false_disable::before {content: @fa-circle-thin;color: @color-disabled} + &.radio_true_full::before {content: @fa-dot-circle-o;} + &.radio_true_full_focus::before {content: @fa-dot-circle-o;color: @color-highlight} + &.radio_true_part::before {content: @fa-dot-circle-o;color: @color-partial} + &.radio_true_part_focus::before {content: @fa-dot-circle-o;color: @color-partial;} + &.radio_true_disable::before {content: @fa-circle-thin;color: @color-disabled} + + } + &.switch {width:@w; height:@h} + &.root_open::before{content: @fa-chevron-down;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;} + &.root_close::before{content: @fa-folder-open-o;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;} + &.roots_open::before{content: @fa-chevron-down;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;} + &.roots_close::before{content: @fa-chevron-right;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;} + &.center_open::before{content: @fa-chevron-down;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;} + &.center_close::before{content: @fa-chevron-right;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;} + &.bottom_open::before{content: @fa-chevron-down;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;} + &.bottom_close::before{content: @fa-chevron-right;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;} + &.noline_open{} + &.noline_close{} + &.root_docu{ background:none;} + &.roots_docu::before{content: @fa-list-alt;padding-left:@pad-left;display: inline-block;color:@color-normal;} + &.center_docu::before{padding-top:@pad-top;padding-left:@pad-left;display: inline-block;color:@color-normal;} + &.bottom_docu::before{padding-top:@pad-top;padding-left:@pad-left;display: inline-block;color:@color-normal;} + &.noline_docu{ background:none;} + + &.ico_open::before {content: @fa-folder-open-o;font-family: FontAwesome;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;color:@color-normal;} + &.ico_close::before {content: @fa-folder-o;font-family: FontAwesome;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;color:@color-normal;} + &.ico_docu::before{content: @fa-list-alt;font-family: FontAwesome;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;color:@color-normal;} + + &.edit {margin-left:4px; margin-right: -1px; vertical-align:top; *vertical-align:middle;padding-top:@pad-top;} + &.edit::before{content: @fa-pencil-square-o;font-family: FontAwesome;} + + &.remove {margin-left:4px; margin-right: -1px; vertical-align:top; *vertical-align:middle;padding-top:@pad-top;} + &.remove::before{content: @fa-trash;font-family: FontAwesome;} + + + &.add {margin-left:4px; margin-right: -1px; vertical-align:top; *vertical-align:middle;padding-top:@pad-top;} + &.add::before{content: @fa-plus;font-family: FontAwesome;} + + &.ico_loading{margin-right:2px; background:url(./img/loading.gif) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle} + } + + } +} + + +ul.tmpTargetzTree {background-color:#FFE6B0; opacity:0.8; filter:alpha(opacity=80)} + +// this is the arrow that moves +span.tmpzTreeMove_arrow{width:16px; height:@h; display: inline-block; + padding:0; margin:2px 0 0 1px; border:0 none; position:absolute; + background-color:transparent; background-attachment: scroll; + } +span.tmpzTreeMove_arrow::before{content: @fa-play;font-family: FontAwesome;color: @color-highlight; + } +// outline + +ul.ztree.zTreeDragUL {margin:0; padding:0; position:absolute; width:auto; height:auto;overflow:hidden; + background-color:#cfcfcf; border:1px @color-highlight dotted; opacity:0.8; filter:alpha(opacity=80)} +.ztreeMask {z-index:10000; background-color:#cfcfcf; opacity:0.0; filter:alpha(opacity=0); position:absolute} + diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/awesomeStyle/fa.less b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/awesomeStyle/fa.less new file mode 100644 index 0000000..3714884 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/awesomeStyle/fa.less @@ -0,0 +1,480 @@ +@fa-glass: "\f000"; +@fa-music: "\f001"; +@fa-search: "\f002"; +@fa-envelope-o: "\f003"; +@fa-heart: "\f004"; +@fa-star: "\f005"; +@fa-star-o: "\f006"; +@fa-user: "\f007"; +@fa-film: "\f008"; +@fa-th-large: "\f009"; +@fa-th: "\f00a"; +@fa-th-list: "\f00b"; +@fa-check: "\f00c"; +@fa-times: "\f00d"; +@fa-search-plus: "\f00e"; +@fa-search-minus: "\f010"; +@fa-power-off: "\f011"; +@fa-signal: "\f012"; +@fa-cog: "\f013"; +@fa-trash-o: "\f014"; +@fa-home: "\f015"; +@fa-file-o: "\f016"; +@fa-clock-o: "\f017"; +@fa-road: "\f018"; +@fa-download: "\f019"; +@fa-arrow-circle-o-down: "\f01a"; +@fa-arrow-circle-o-up: "\f01b"; +@fa-inbox: "\f01c"; +@fa-play-circle-o: "\f01d"; +@fa-repeat: "\f01e"; +@fa-refresh: "\f021"; +@fa-list-alt: "\f022"; +@fa-lock: "\f023"; +@fa-flag: "\f024"; +@fa-headphones: "\f025"; +@fa-volume-off: "\f026"; +@fa-volume-down: "\f027"; +@fa-volume-up: "\f028"; +@fa-qrcode: "\f029"; +@fa-barcode: "\f02a"; +@fa-tag: "\f02b"; +@fa-tags: "\f02c"; +@fa-book: "\f02d"; +@fa-bookmark: "\f02e"; +@fa-print: "\f02f"; +@fa-camera: "\f030"; +@fa-font: "\f031"; +@fa-bold: "\f032"; +@fa-italic: "\f033"; +@fa-text-height: "\f034"; +@fa-text-width: "\f035"; +@fa-align-left: "\f036"; +@fa-align-center: "\f037"; +@fa-align-right: "\f038"; +@fa-align-justify: "\f039"; +@fa-list: "\f03a"; +@fa-outdent: "\f03b"; +@fa-indent: "\f03c"; +@fa-video-camera: "\f03d"; +@fa-picture-o: "\f03e"; +@fa-pencil: "\f040"; +@fa-map-marker: "\f041"; +@fa-adjust: "\f042"; +@fa-tint: "\f043"; +@fa-pencil-square-o: "\f044"; +@fa-share-square-o: "\f045"; +@fa-check-square-o: "\f046"; +@fa-arrows: "\f047"; +@fa-step-backward: "\f048"; +@fa-fast-backward: "\f049"; +@fa-backward: "\f04a"; +@fa-play: "\f04b"; +@fa-pause: "\f04c"; +@fa-stop: "\f04d"; +@fa-forward: "\f04e"; +@fa-fast-forward: "\f050"; +@fa-step-forward: "\f051"; +@fa-eject: "\f052"; +@fa-chevron-left: "\f053"; +@fa-chevron-right: "\f054"; +@fa-plus-circle: "\f055"; +@fa-minus-circle: "\f056"; +@fa-times-circle: "\f057"; +@fa-check-circle: "\f058"; +@fa-question-circle: "\f059"; +@fa-info-circle: "\f05a"; +@fa-crosshairs: "\f05b"; +@fa-times-circle-o: "\f05c"; +@fa-check-circle-o: "\f05d"; +@fa-ban: "\f05e"; +@fa-arrow-left: "\f060"; +@fa-arrow-right: "\f061"; +@fa-arrow-up: "\f062"; +@fa-arrow-down: "\f063"; +@fa-share: "\f064"; +@fa-expand: "\f065"; +@fa-compress: "\f066"; +@fa-plus: "\f067"; +@fa-minus: "\f068"; +@fa-asterisk: "\f069"; +@fa-exclamation-circle: "\f06a"; +@fa-gift: "\f06b"; +@fa-leaf: "\f06c"; +@fa-fire: "\f06d"; +@fa-eye: "\f06e"; +@fa-eye-slash: "\f070"; +@fa-exclamation-triangle: "\f071"; +@fa-plane: "\f072"; +@fa-calendar: "\f073"; +@fa-random: "\f074"; +@fa-comment: "\f075"; +@fa-magnet: "\f076"; +@fa-chevron-up: "\f077"; +@fa-chevron-down: "\f078"; +@fa-retweet: "\f079"; +@fa-shopping-cart: "\f07a"; +@fa-folder: "\f07b"; +@fa-folder-open: "\f07c"; +@fa-arrows-v: "\f07d"; +@fa-arrows-h: "\f07e"; +@fa-bar-chart: "\f080"; +@fa-twitter-square: "\f081"; +@fa-facebook-square: "\f082"; +@fa-camera-retro: "\f083"; +@fa-key: "\f084"; +@fa-cogs: "\f085"; +@fa-comments: "\f086"; +@fa-thumbs-o-up: "\f087"; +@fa-thumbs-o-down: "\f088"; +@fa-star-half: "\f089"; +@fa-heart-o: "\f08a"; +@fa-sign-out: "\f08b"; +@fa-linkedin-square: "\f08c"; +@fa-thumb-tack: "\f08d"; +@fa-external-link: "\f08e"; +@fa-sign-in: "\f090"; +@fa-trophy: "\f091"; +@fa-github-square: "\f092"; +@fa-upload: "\f093"; +@fa-lemon-o: "\f094"; +@fa-phone: "\f095"; +@fa-square-o: "\f096"; +@fa-bookmark-o: "\f097"; +@fa-phone-square: "\f098"; +@fa-twitter: "\f099"; +@fa-facebook: "\f09a"; +@fa-github: "\f09b"; +@fa-unlock: "\f09c"; +@fa-credit-card: "\f09d"; +@fa-rss: "\f09e"; +@fa-hdd-o: "\f0a0"; +@fa-bullhorn: "\f0a1"; +@fa-bell: "\f0f3"; +@fa-certificate: "\f0a3"; +@fa-hand-o-right: "\f0a4"; +@fa-hand-o-left: "\f0a5"; +@fa-hand-o-up: "\f0a6"; +@fa-hand-o-down: "\f0a7"; +@fa-arrow-circle-left: "\f0a8"; +@fa-arrow-circle-right: "\f0a9"; +@fa-arrow-circle-up: "\f0aa"; +@fa-arrow-circle-down: "\f0ab"; +@fa-globe: "\f0ac"; +@fa-wrench: "\f0ad"; +@fa-tasks: "\f0ae"; +@fa-filter: "\f0b0"; +@fa-briefcase: "\f0b1"; +@fa-arrows-alt: "\f0b2"; +@fa-users: "\f0c0"; +@fa-link: "\f0c1"; +@fa-cloud: "\f0c2"; +@fa-flask: "\f0c3"; +@fa-scissors: "\f0c4"; +@fa-files-o: "\f0c5"; +@fa-paperclip: "\f0c6"; +@fa-floppy-o: "\f0c7"; +@fa-square: "\f0c8"; +@fa-bars: "\f0c9"; +@fa-list-ul: "\f0ca"; +@fa-list-ol: "\f0cb"; +@fa-strikethrough: "\f0cc"; +@fa-underline: "\f0cd"; +@fa-table: "\f0ce"; +@fa-magic: "\f0d0"; +@fa-truck: "\f0d1"; +@fa-pinterest: "\f0d2"; +@fa-pinterest-square: "\f0d3"; +@fa-google-plus-square: "\f0d4"; +@fa-google-plus: "\f0d5"; +@fa-money: "\f0d6"; +@fa-caret-down: "\f0d7"; +@fa-caret-up: "\f0d8"; +@fa-caret-left: "\f0d9"; +@fa-caret-right: "\f0da"; +@fa-columns: "\f0db"; +@fa-sort: "\f0dc"; +@fa-sort-desc: "\f0dd"; +@fa-sort-asc: "\f0de"; +@fa-envelope: "\f0e0"; +@fa-linkedin: "\f0e1"; +@fa-undo: "\f0e2"; +@fa-gavel: "\f0e3"; +@fa-tachometer: "\f0e4"; +@fa-comment-o: "\f0e5"; +@fa-comments-o: "\f0e6"; +@fa-bolt: "\f0e7"; +@fa-sitemap: "\f0e8"; +@fa-umbrella: "\f0e9"; +@fa-clipboard: "\f0ea"; +@fa-lightbulb-o: "\f0eb"; +@fa-exchange: "\f0ec"; +@fa-cloud-download: "\f0ed"; +@fa-cloud-upload: "\f0ee"; +@fa-user-md: "\f0f0"; +@fa-stethoscope: "\f0f1"; +@fa-suitcase: "\f0f2"; +@fa-bell-o: "\f0a2"; +@fa-coffee: "\f0f4"; +@fa-cutlery: "\f0f5"; +@fa-file-text-o: "\f0f6"; +@fa-building-o: "\f0f7"; +@fa-hospital-o: "\f0f8"; +@fa-ambulance: "\f0f9"; +@fa-medkit: "\f0fa"; +@fa-fighter-jet: "\f0fb"; +@fa-beer: "\f0fc"; +@fa-h-square: "\f0fd"; +@fa-plus-square: "\f0fe"; +@fa-angle-double-left: "\f100"; +@fa-angle-double-right: "\f101"; +@fa-angle-double-up: "\f102"; +@fa-angle-double-down: "\f103"; +@fa-angle-left: "\f104"; +@fa-angle-right: "\f105"; +@fa-angle-up: "\f106"; +@fa-angle-down: "\f107"; +@fa-desktop: "\f108"; +@fa-laptop: "\f109"; +@fa-tablet: "\f10a"; +@fa-mobile: "\f10b"; +@fa-circle-o: "\f10c"; +@fa-quote-left: "\f10d"; +@fa-quote-right: "\f10e"; +@fa-spinner: "\f110"; +@fa-circle: "\f111"; +@fa-reply: "\f112"; +@fa-github-alt: "\f113"; +@fa-folder-o: "\f114"; +@fa-folder-open-o: "\f115"; +@fa-smile-o: "\f118"; +@fa-frown-o: "\f119"; +@fa-meh-o: "\f11a"; +@fa-gamepad: "\f11b"; +@fa-keyboard-o: "\f11c"; +@fa-flag-o: "\f11d"; +@fa-flag-checkered: "\f11e"; +@fa-terminal: "\f120"; +@fa-code: "\f121"; +@fa-reply-all: "\f122"; +@fa-star-half-o: "\f123"; +@fa-location-arrow: "\f124"; +@fa-crop: "\f125"; +@fa-code-fork: "\f126"; +@fa-chain-broken: "\f127"; +@fa-question: "\f128"; +@fa-info: "\f129"; +@fa-exclamation: "\f12a"; +@fa-superscript: "\f12b"; +@fa-subscript: "\f12c"; +@fa-eraser: "\f12d"; +@fa-puzzle-piece: "\f12e"; +@fa-microphone: "\f130"; +@fa-microphone-slash: "\f131"; +@fa-shield: "\f132"; +@fa-calendar-o: "\f133"; +@fa-fire-extinguisher: "\f134"; +@fa-rocket: "\f135"; +@fa-maxcdn: "\f136"; +@fa-chevron-circle-left: "\f137"; +@fa-chevron-circle-right: "\f138"; +@fa-chevron-circle-up: "\f139"; +@fa-chevron-circle-down: "\f13a"; +@fa-html5: "\f13b"; +@fa-css3: "\f13c"; +@fa-anchor: "\f13d"; +@fa-unlock-alt: "\f13e"; +@fa-bullseye: "\f140"; +@fa-ellipsis-h: "\f141"; +@fa-ellipsis-v: "\f142"; +@fa-rss-square: "\f143"; +@fa-play-circle: "\f144"; +@fa-ticket: "\f145"; +@fa-minus-square: "\f146"; +@fa-minus-square-o: "\f147"; +@fa-level-up: "\f148"; +@fa-level-down: "\f149"; +@fa-check-square: "\f14a"; +@fa-pencil-square: "\f14b"; +@fa-external-link-square: "\f14c"; +@fa-share-square: "\f14d"; +@fa-compass: "\f14e"; +@fa-caret-square-o-down: "\f150"; +@fa-caret-square-o-up: "\f151"; +@fa-caret-square-o-right: "\f152"; +@fa-eur: "\f153"; +@fa-gbp: "\f154"; +@fa-usd: "\f155"; +@fa-inr: "\f156"; +@fa-jpy: "\f157"; +@fa-rub: "\f158"; +@fa-krw: "\f159"; +@fa-btc: "\f15a"; +@fa-file: "\f15b"; +@fa-file-text: "\f15c"; +@fa-sort-alpha-asc: "\f15d"; +@fa-sort-alpha-desc: "\f15e"; +@fa-sort-amount-asc: "\f160"; +@fa-sort-amount-desc: "\f161"; +@fa-sort-numeric-asc: "\f162"; +@fa-sort-numeric-desc: "\f163"; +@fa-thumbs-up: "\f164"; +@fa-thumbs-down: "\f165"; +@fa-youtube-square: "\f166"; +@fa-youtube: "\f167"; +@fa-xing: "\f168"; +@fa-xing-square: "\f169"; +@fa-youtube-play: "\f16a"; +@fa-dropbox: "\f16b"; +@fa-stack-overflow: "\f16c"; +@fa-instagram: "\f16d"; +@fa-flickr: "\f16e"; +@fa-adn: "\f170"; +@fa-bitbucket: "\f171"; +@fa-bitbucket-square: "\f172"; +@fa-tumblr: "\f173"; +@fa-tumblr-square: "\f174"; +@fa-long-arrow-down: "\f175"; +@fa-long-arrow-up: "\f176"; +@fa-long-arrow-left: "\f177"; +@fa-long-arrow-right: "\f178"; +@fa-apple: "\f179"; +@fa-windows: "\f17a"; +@fa-android: "\f17b"; +@fa-linux: "\f17c"; +@fa-dribbble: "\f17d"; +@fa-skype: "\f17e"; +@fa-foursquare: "\f180"; +@fa-trello: "\f181"; +@fa-female: "\f182"; +@fa-male: "\f183"; +@fa-gittip: "\f184"; +@fa-sun-o: "\f185"; +@fa-moon-o: "\f186"; +@fa-archive: "\f187"; +@fa-bug: "\f188"; +@fa-vk: "\f189"; +@fa-weibo: "\f18a"; +@fa-renren: "\f18b"; +@fa-pagelines: "\f18c"; +@fa-stack-exchange: "\f18d"; +@fa-arrow-circle-o-right: "\f18e"; +@fa-arrow-circle-o-left: "\f190"; +@fa-caret-square-o-left: "\f191"; +@fa-dot-circle-o: "\f192"; +@fa-wheelchair: "\f193"; +@fa-vimeo-square: "\f194"; +@fa-try: "\f195"; +@fa-plus-square-o: "\f196"; +@fa-space-shuttle: "\f197"; +@fa-slack: "\f198"; +@fa-envelope-square: "\f199"; +@fa-wordpress: "\f19a"; +@fa-openid: "\f19b"; +@fa-university: "\f19c"; +@fa-graduation-cap: "\f19d"; +@fa-yahoo: "\f19e"; +@fa-google: "\f1a0"; +@fa-reddit: "\f1a1"; +@fa-reddit-square: "\f1a2"; +@fa-stumbleupon-circle: "\f1a3"; +@fa-stumbleupon: "\f1a4"; +@fa-delicious: "\f1a5"; +@fa-digg: "\f1a6"; +@fa-pied-piper: "\f1a7"; +@fa-pied-piper-alt: "\f1a8"; +@fa-drupal: "\f1a9"; +@fa-joomla: "\f1aa"; +@fa-language: "\f1ab"; +@fa-fax: "\f1ac"; +@fa-building: "\f1ad"; +@fa-child: "\f1ae"; +@fa-paw: "\f1b0"; +@fa-spoon: "\f1b1"; +@fa-cube: "\f1b2"; +@fa-cubes: "\f1b3"; +@fa-behance: "\f1b4"; +@fa-behance-square: "\f1b5"; +@fa-steam: "\f1b6"; +@fa-steam-square: "\f1b7"; +@fa-recycle: "\f1b8"; +@fa-car: "\f1b9"; +@fa-taxi: "\f1ba"; +@fa-tree: "\f1bb"; +@fa-spotify: "\f1bc"; +@fa-deviantart: "\f1bd"; +@fa-soundcloud: "\f1be"; +@fa-database: "\f1c0"; +@fa-file-pdf-o: "\f1c1"; +@fa-file-word-o: "\f1c2"; +@fa-file-excel-o: "\f1c3"; +@fa-file-powerpoint-o: "\f1c4"; +@fa-file-image-o: "\f1c5"; +@fa-file-archive-o: "\f1c6"; +@fa-file-audio-o: "\f1c7"; +@fa-file-video-o: "\f1c8"; +@fa-file-code-o: "\f1c9"; +@fa-vine: "\f1ca"; +@fa-codepen: "\f1cb"; +@fa-jsfiddle: "\f1cc"; +@fa-life-ring: "\f1cd"; +@fa-circle-o-notch: "\f1ce"; +@fa-rebel: "\f1d0"; +@fa-empire: "\f1d1"; +@fa-git-square: "\f1d2"; +@fa-git: "\f1d3"; +@fa-hacker-news: "\f1d4"; +@fa-tencent-weibo: "\f1d5"; +@fa-qq: "\f1d6"; +@fa-weixin: "\f1d7"; +@fa-paper-plane: "\f1d8"; +@fa-paper-plane-o: "\f1d9"; +@fa-history: "\f1da"; +@fa-circle-thin: "\f1db"; +@fa-header: "\f1dc"; +@fa-paragraph: "\f1dd"; +@fa-sliders: "\f1de"; +@fa-share-alt: "\f1e0"; +@fa-share-alt-square: "\f1e1"; +@fa-bomb: "\f1e2"; +@fa-futbol-o: "\f1e3"; +@fa-tty: "\f1e4"; +@fa-binoculars: "\f1e5"; +@fa-plug: "\f1e6"; +@fa-slideshare: "\f1e7"; +@fa-twitch: "\f1e8"; +@fa-yelp: "\f1e9"; +@fa-newspaper-o: "\f1ea"; +@fa-wifi: "\f1eb"; +@fa-calculator: "\f1ec"; +@fa-paypal: "\f1ed"; +@fa-google-wallet: "\f1ee"; +@fa-cc-visa: "\f1f0"; +@fa-cc-mastercard: "\f1f1"; +@fa-cc-discover: "\f1f2"; +@fa-cc-amex: "\f1f3"; +@fa-cc-paypal: "\f1f4"; +@fa-cc-stripe: "\f1f5"; +@fa-bell-slash: "\f1f6"; +@fa-bell-slash-o: "\f1f7"; +@fa-trash: "\f1f8"; +@fa-copyright: "\f1f9"; +@fa-at: "\f1fa"; +@fa-eyedropper: "\f1fb"; +@fa-paint-brush: "\f1fc"; +@fa-birthday-cake: "\f1fd"; +@fa-area-chart: "\f1fe"; +@fa-pie-chart: "\f200"; +@fa-line-chart: "\f201"; +@fa-lastfm: "\f202"; +@fa-lastfm-square: "\f203"; +@fa-toggle-off: "\f204"; +@fa-toggle-on: "\f205"; +@fa-bicycle: "\f206"; +@fa-bus: "\f207"; +@fa-ioxhost: "\f208"; +@fa-angellist: "\f209"; +@fa-cc: "\f20a"; +@fa-ils: "\f20b"; +@fa-meanpath: "\f20c"; + diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/awesomeStyle/img/loading.gif b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/awesomeStyle/img/loading.gif new file mode 100644 index 0000000..e8c2892 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/awesomeStyle/img/loading.gif differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/metroStyle/img/line_conn.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/metroStyle/img/line_conn.png new file mode 100644 index 0000000..b211da2 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/metroStyle/img/line_conn.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/metroStyle/img/loading.gif b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/metroStyle/img/loading.gif new file mode 100644 index 0000000..e8c2892 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/metroStyle/img/loading.gif differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/metroStyle/img/metro.gif b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/metroStyle/img/metro.gif new file mode 100644 index 0000000..664b969 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/metroStyle/img/metro.gif differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/metroStyle/img/metro.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/metroStyle/img/metro.png new file mode 100644 index 0000000..e9e58a3 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/metroStyle/img/metro.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/metroStyle/metroStyle.css b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/metroStyle/metroStyle.css new file mode 100644 index 0000000..af81f42 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/metroStyle/metroStyle.css @@ -0,0 +1,96 @@ +/*------------------------------------- +zTree Style + +version: 3.4 +author: Hunter.z +email: hunter.z@263.net +website: http://code.google.com/p/jquerytree/ + +-------------------------------------*/ + +.ztree * {padding:0; margin:0; font-size:12px; font-family: Verdana, Arial, Helvetica, AppleGothic, sans-serif} +.ztree {margin:0; padding:5px; color:#333} +.ztree li{padding:0; margin:0; list-style:none; line-height:17px; text-align:left; white-space:nowrap; outline:0} +.ztree li ul{ margin:0; padding:0 0 0 18px} +.ztree li ul.line{ background:url(./img/line_conn.png) 0 0 repeat-y;} + +.ztree li a {padding-right:3px; margin:0; cursor:pointer; height:21px; color:#333; background-color: transparent; text-decoration:none; vertical-align:top; display: inline-block} +.ztree li a:hover {text-decoration:underline} +.ztree li a.curSelectedNode {padding-top:0px; background-color:#e5e5e5; color:black; height:21px; opacity:0.8;} +.ztree li a.curSelectedNode_Edit {padding-top:0px; background-color:#e5e5e5; color:black; height:21px; border:1px #666 solid; opacity:0.8;} +.ztree li a.tmpTargetNode_inner {padding-top:0px; background-color:#aaa; color:white; height:21px; border:1px #666 solid; + opacity:0.8; filter:alpha(opacity=80)} +.ztree li a.tmpTargetNode_prev {} +.ztree li a.tmpTargetNode_next {} +.ztree li a input.rename {height:14px; width:80px; padding:0; margin:0; + font-size:12px; border:1px #585956 solid; *border:0px} +.ztree li span {line-height:21px; margin-right:2px} +.ztree li span.button {line-height:0; margin:0; padding: 0; width:21px; height:21px; display: inline-block; vertical-align:middle; + border:0 none; cursor: pointer;outline:none; + background-color:transparent; background-repeat:no-repeat; background-attachment: scroll; + background-image:url("./img/metro.png"); *background-image:url("./img/metro.gif")} + +.ztree li span.button.chk {width:13px; height:13px; margin:0 2px; cursor: auto} +.ztree li span.button.chk.checkbox_false_full {background-position: -5px -5px;} +.ztree li span.button.chk.checkbox_false_full_focus {background-position: -5px -26px;} +.ztree li span.button.chk.checkbox_false_part {background-position: -5px -48px;} +.ztree li span.button.chk.checkbox_false_part_focus {background-position: -5px -68px;} +.ztree li span.button.chk.checkbox_false_disable {background-position: -5px -89px;} +.ztree li span.button.chk.checkbox_true_full {background-position: -26px -5px;} +.ztree li span.button.chk.checkbox_true_full_focus {background-position: -26px -26px;} +.ztree li span.button.chk.checkbox_true_part {background-position: -26px -48px;} +.ztree li span.button.chk.checkbox_true_part_focus {background-position: -26px -68px;} +.ztree li span.button.chk.checkbox_true_disable {background-position: -26px -89px;} +.ztree li span.button.chk.radio_false_full {background-position: -47px -5px;} +.ztree li span.button.chk.radio_false_full_focus {background-position: -47px -26px;} +.ztree li span.button.chk.radio_false_part {background-position: -47px -47px;} +.ztree li span.button.chk.radio_false_part_focus {background-position: -47px -68px;} +.ztree li span.button.chk.radio_false_disable {background-position: -47px -89px;} +.ztree li span.button.chk.radio_true_full {background-position: -68px -5px;} +.ztree li span.button.chk.radio_true_full_focus {background-position: -68px -26px;} +.ztree li span.button.chk.radio_true_part {background-position: -68px -47px;} +.ztree li span.button.chk.radio_true_part_focus {background-position: -68px -68px;} +.ztree li span.button.chk.radio_true_disable {background-position: -68px -89px;} + +.ztree li span.button.switch {width:21px; height:21px} +.ztree li span.button.root_open{background-position:-105px -63px} +.ztree li span.button.root_close{background-position:-126px -63px} +.ztree li span.button.roots_open{background-position: -105px 0;} +.ztree li span.button.roots_close{background-position: -126px 0;} +.ztree li span.button.center_open{background-position: -105px -21px;} +.ztree li span.button.center_close{background-position: -126px -21px;} +.ztree li span.button.bottom_open{background-position: -105px -42px;} +.ztree li span.button.bottom_close{background-position: -126px -42px;} +.ztree li span.button.noline_open{background-position: -105px -84px;} +.ztree li span.button.noline_close{background-position: -126px -84px;} +.ztree li span.button.root_docu{ background:none;} +.ztree li span.button.roots_docu{background-position: -84px 0;} +.ztree li span.button.center_docu{background-position: -84px -21px;} +.ztree li span.button.bottom_docu{background-position: -84px -42px;} +.ztree li span.button.noline_docu{ background:none;} + +.ztree li span.button.ico_open{margin-right:2px; background-position: -147px -21px; vertical-align:top; *vertical-align:middle} +.ztree li span.button.ico_close{margin-right:2px; margin-right:2px; background-position: -147px 0; vertical-align:top; *vertical-align:middle} +.ztree li span.button.ico_docu{margin-right:2px; background-position: -147px -42px; vertical-align:top; *vertical-align:middle} +.ztree li span.button.edit {margin-left:2px; margin-right: -1px; background-position: -189px -21px; vertical-align:top; *vertical-align:middle} +.ztree li span.button.edit:hover { + background-position: -168px -21px; +} +.ztree li span.button.remove {margin-left:2px; margin-right: -1px; background-position: -189px -42px; vertical-align:top; *vertical-align:middle} +.ztree li span.button.remove:hover { + background-position: -168px -42px; +} +.ztree li span.button.add {margin-left:2px; margin-right: -1px; background-position: -189px 0; vertical-align:top; *vertical-align:middle} +.ztree li span.button.add:hover { + background-position: -168px 0; +} +.ztree li span.button.ico_loading{margin-right:2px; background:url(./img/loading.gif) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle} + +ul.tmpTargetzTree {background-color:#FFE6B0; opacity:0.8; filter:alpha(opacity=80)} + +span.tmpzTreeMove_arrow {width:16px; height:21px; display: inline-block; padding:0; margin:2px 0 0 1px; border:0 none; position:absolute; + background-color:transparent; background-repeat:no-repeat; background-attachment: scroll; + background-position:-168px -84px; background-image:url("./img/metro.png"); *background-image:url("./img/metro.gif")} + +ul.ztree.zTreeDragUL {margin:0; padding:0; position:absolute; width:auto; height:auto;overflow:hidden; background-color:#cfcfcf; border:1px #00B83F dotted; opacity:0.8; filter:alpha(opacity=80)} +.ztreeMask {z-index:10000; background-color:#cfcfcf; opacity:0.0; filter:alpha(opacity=0); position:absolute} diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/1_close.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/1_close.png new file mode 100644 index 0000000..68ccb3c Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/1_close.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/1_open.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/1_open.png new file mode 100644 index 0000000..d6ff36d Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/1_open.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/2.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/2.png new file mode 100644 index 0000000..9eff506 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/2.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/3.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/3.png new file mode 100644 index 0000000..d7ba6d0 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/3.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/4.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/4.png new file mode 100644 index 0000000..753e2bf Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/4.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/5.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/5.png new file mode 100644 index 0000000..0c5eccd Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/5.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/6.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/6.png new file mode 100644 index 0000000..070b835 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/6.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/7.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/7.png new file mode 100644 index 0000000..532b037 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/7.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/8.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/8.png new file mode 100644 index 0000000..a8f3a86 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/8.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/9.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/9.png new file mode 100644 index 0000000..4db73cd Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/diy/9.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/line_conn.gif b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/line_conn.gif new file mode 100644 index 0000000..d561d36 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/line_conn.gif differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/loading.gif b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/loading.gif new file mode 100644 index 0000000..e8c2892 Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/loading.gif differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/zTreeStandard.gif b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/zTreeStandard.gif new file mode 100644 index 0000000..50c94fd Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/zTreeStandard.gif differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/zTreeStandard.png b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/zTreeStandard.png new file mode 100644 index 0000000..ffda01e Binary files /dev/null and b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/img/zTreeStandard.png differ diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/zTreeStyle.css b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/zTreeStyle.css new file mode 100644 index 0000000..4a1705b --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/css/zTreeStyle/zTreeStyle.css @@ -0,0 +1,97 @@ +/*------------------------------------- +zTree Style + +version: 3.5.19 +author: Hunter.z +email: hunter.z@263.net +website: http://code.google.com/p/jquerytree/ + +-------------------------------------*/ + +.ztree * {padding:0; margin:0; font-size:12px; font-family: Verdana, Arial, Helvetica, AppleGothic, sans-serif} +.ztree {margin:0; padding:5px; color:#333} +.ztree li{padding:0; margin:0; list-style:none; line-height:14px; text-align:left; white-space:nowrap; outline:0} +.ztree li ul{ margin:0; padding:0 0 0 18px} +.ztree li ul.line{ background:url(./img/line_conn.gif) 0 0 repeat-y;} + +.ztree li a {padding:1px 3px 0 0; margin:0; cursor:pointer; height:17px; color:#333; background-color: transparent; + text-decoration:none; vertical-align:top; display: inline-block} +.ztree li a:hover {text-decoration:underline} +.ztree li a.curSelectedNode {padding-top:0px; background-color:#FFE6B0; color:black; height:16px; border:1px #FFB951 solid; opacity:0.8;} +.ztree li a.curSelectedNode_Edit {padding-top:0px; background-color:#FFE6B0; color:black; height:16px; border:1px #FFB951 solid; opacity:0.8;} +.ztree li a.tmpTargetNode_inner {padding-top:0px; background-color:#316AC5; color:white; height:16px; border:1px #316AC5 solid; + opacity:0.8; filter:alpha(opacity=80)} +.ztree li a.tmpTargetNode_prev {} +.ztree li a.tmpTargetNode_next {} +.ztree li a input.rename {height:14px; width:80px; padding:0; margin:0; + font-size:12px; border:1px #7EC4CC solid; *border:0px} +.ztree li span {line-height:16px; margin-right:2px} +.ztree li span.button {line-height:0; margin:0; width:16px; height:16px; display: inline-block; vertical-align:middle; + border:0 none; cursor: pointer;outline:none; + background-color:transparent; background-repeat:no-repeat; background-attachment: scroll; + background-image:url("./img/zTreeStandard.png"); *background-image:url("./img/zTreeStandard.gif")} + +.ztree li span.button.chk {width:13px; height:13px; margin:0 3px 0 0; cursor: auto} +.ztree li span.button.chk.checkbox_false_full {background-position:0 0} +.ztree li span.button.chk.checkbox_false_full_focus {background-position:0 -14px} +.ztree li span.button.chk.checkbox_false_part {background-position:0 -28px} +.ztree li span.button.chk.checkbox_false_part_focus {background-position:0 -42px} +.ztree li span.button.chk.checkbox_false_disable {background-position:0 -56px} +.ztree li span.button.chk.checkbox_true_full {background-position:-14px 0} +.ztree li span.button.chk.checkbox_true_full_focus {background-position:-14px -14px} +.ztree li span.button.chk.checkbox_true_part {background-position:-14px -28px} +.ztree li span.button.chk.checkbox_true_part_focus {background-position:-14px -42px} +.ztree li span.button.chk.checkbox_true_disable {background-position:-14px -56px} +.ztree li span.button.chk.radio_false_full {background-position:-28px 0} +.ztree li span.button.chk.radio_false_full_focus {background-position:-28px -14px} +.ztree li span.button.chk.radio_false_part {background-position:-28px -28px} +.ztree li span.button.chk.radio_false_part_focus {background-position:-28px -42px} +.ztree li span.button.chk.radio_false_disable {background-position:-28px -56px} +.ztree li span.button.chk.radio_true_full {background-position:-42px 0} +.ztree li span.button.chk.radio_true_full_focus {background-position:-42px -14px} +.ztree li span.button.chk.radio_true_part {background-position:-42px -28px} +.ztree li span.button.chk.radio_true_part_focus {background-position:-42px -42px} +.ztree li span.button.chk.radio_true_disable {background-position:-42px -56px} + +.ztree li span.button.switch {width:18px; height:18px} +.ztree li span.button.root_open{background-position:-92px -54px} +.ztree li span.button.root_close{background-position:-74px -54px} +.ztree li span.button.roots_open{background-position:-92px 0} +.ztree li span.button.roots_close{background-position:-74px 0} +.ztree li span.button.center_open{background-position:-92px -18px} +.ztree li span.button.center_close{background-position:-74px -18px} +.ztree li span.button.bottom_open{background-position:-92px -36px} +.ztree li span.button.bottom_close{background-position:-74px -36px} +.ztree li span.button.noline_open{background-position:-92px -72px} +.ztree li span.button.noline_close{background-position:-74px -72px} +.ztree li span.button.root_docu{ background:none;} +.ztree li span.button.roots_docu{background-position:-56px 0} +.ztree li span.button.center_docu{background-position:-56px -18px} +.ztree li span.button.bottom_docu{background-position:-56px -36px} +.ztree li span.button.noline_docu{ background:none;} + +.ztree li span.button.ico_open{margin-right:2px; background-position:-110px -16px; vertical-align:top; *vertical-align:middle} +.ztree li span.button.ico_close{margin-right:2px; background-position:-110px 0; vertical-align:top; *vertical-align:middle} +.ztree li span.button.ico_docu{margin-right:2px; background-position:-110px -32px; vertical-align:top; *vertical-align:middle} +.ztree li span.button.edit {margin-right:2px; background-position:-110px -48px; vertical-align:top; *vertical-align:middle} +.ztree li span.button.remove {margin-right:2px; background-position:-110px -64px; vertical-align:top; *vertical-align:middle} + +.ztree li span.button.ico_loading{margin-right:2px; background:url(./img/loading.gif) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle} + +ul.tmpTargetzTree {background-color:#FFE6B0; opacity:0.8; filter:alpha(opacity=80)} + +span.tmpzTreeMove_arrow {width:16px; height:16px; display: inline-block; padding:0; margin:2px 0 0 1px; border:0 none; position:absolute; + background-color:transparent; background-repeat:no-repeat; background-attachment: scroll; + background-position:-110px -80px; background-image:url("./img/zTreeStandard.png"); *background-image:url("./img/zTreeStandard.gif")} + +ul.ztree.zTreeDragUL {margin:0; padding:0; position:absolute; width:auto; height:auto;overflow:hidden; background-color:#cfcfcf; border:1px #00B83F dotted; opacity:0.8; filter:alpha(opacity=80)} +.zTreeMask {z-index:10000; background-color:#cfcfcf; opacity:0.0; filter:alpha(opacity=0); position:absolute} + +/* level style*/ +/*.ztree li span.button.level0 { + display:none; +} +.ztree li ul.level0 { + padding:0; + background:none; +}*/ \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/jquery.ztree.all.min.js b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/jquery.ztree.all.min.js new file mode 100644 index 0000000..8be21e7 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/static/plugins/ztree/jquery.ztree.all.min.js @@ -0,0 +1,165 @@ + +/* + * JQuery zTree core v3.5.26 + * http://zTree.me/ + * + * Copyright (c) 2010 Hunter.z + * + * Licensed same as jquery - MIT License + * http://www.opensource.org/licenses/mit-license.php + * + * email: hunter.z@263.net + * Date: 2016-11-03 + */ +(function(q){var H,I,J,K,L,M,u,r={},v={},w={},N={treeId:"",treeObj:null,view:{addDiyDom:null,autoCancelSelected:!0,dblClickExpand:!0,expandSpeed:"fast",fontCss:{},nameIsHTML:!1,selectedMulti:!0,showIcon:!0,showLine:!0,showTitle:!0,txtSelectedEnable:!1},data:{key:{children:"children",name:"name",title:"",url:"url",icon:"icon"},simpleData:{enable:!1,idKey:"id",pIdKey:"pId",rootPId:null},keep:{parent:!1,leaf:!1}},async:{enable:!1,contentType:"application/x-www-form-urlencoded",type:"post",dataType:"text", +url:"",autoParam:[],otherParam:[],dataFilter:null},callback:{beforeAsync:null,beforeClick:null,beforeDblClick:null,beforeRightClick:null,beforeMouseDown:null,beforeMouseUp:null,beforeExpand:null,beforeCollapse:null,beforeRemove:null,onAsyncError:null,onAsyncSuccess:null,onNodeCreated:null,onClick:null,onDblClick:null,onRightClick:null,onMouseDown:null,onMouseUp:null,onExpand:null,onCollapse:null,onRemove:null}},x=[function(b){var a=b.treeObj,c=f.event;a.bind(c.NODECREATED,function(a,c,g){j.apply(b.callback.onNodeCreated, +[a,c,g])});a.bind(c.CLICK,function(a,c,g,l,h){j.apply(b.callback.onClick,[c,g,l,h])});a.bind(c.EXPAND,function(a,c,g){j.apply(b.callback.onExpand,[a,c,g])});a.bind(c.COLLAPSE,function(a,c,g){j.apply(b.callback.onCollapse,[a,c,g])});a.bind(c.ASYNC_SUCCESS,function(a,c,g,l){j.apply(b.callback.onAsyncSuccess,[a,c,g,l])});a.bind(c.ASYNC_ERROR,function(a,c,g,l,h,f){j.apply(b.callback.onAsyncError,[a,c,g,l,h,f])});a.bind(c.REMOVE,function(a,c,g){j.apply(b.callback.onRemove,[a,c,g])});a.bind(c.SELECTED, +function(a,c,g){j.apply(b.callback.onSelected,[c,g])});a.bind(c.UNSELECTED,function(a,c,g){j.apply(b.callback.onUnSelected,[c,g])})}],y=[function(b){var a=f.event;b.treeObj.unbind(a.NODECREATED).unbind(a.CLICK).unbind(a.EXPAND).unbind(a.COLLAPSE).unbind(a.ASYNC_SUCCESS).unbind(a.ASYNC_ERROR).unbind(a.REMOVE).unbind(a.SELECTED).unbind(a.UNSELECTED)}],z=[function(b){var a=h.getCache(b);a||(a={},h.setCache(b,a));a.nodes=[];a.doms=[]}],A=[function(b,a,c,d,e,g){if(c){var l=h.getRoot(b),f=b.data.key.children; +c.level=a;c.tId=b.treeId+"_"+ ++l.zId;c.parentTId=d?d.tId:null;c.open=typeof c.open=="string"?j.eqs(c.open,"true"):!!c.open;c[f]&&c[f].length>0?(c.isParent=!0,c.zAsync=!0):(c.isParent=typeof c.isParent=="string"?j.eqs(c.isParent,"true"):!!c.isParent,c.open=c.isParent&&!b.async.enable?c.open:!1,c.zAsync=!c.isParent);c.isFirstNode=e;c.isLastNode=g;c.getParentNode=function(){return h.getNodeCache(b,c.parentTId)};c.getPreNode=function(){return h.getPreNode(b,c)};c.getNextNode=function(){return h.getNextNode(b, +c)};c.getIndex=function(){return h.getNodeIndex(b,c)};c.getPath=function(){return h.getNodePath(b,c)};c.isAjaxing=!1;h.fixPIdKeyValue(b,c)}}],t=[function(b){var a=b.target,c=h.getSetting(b.data.treeId),d="",e=null,g="",l="",i=null,n=null,k=null;if(j.eqs(b.type,"mousedown"))l="mousedown";else if(j.eqs(b.type,"mouseup"))l="mouseup";else if(j.eqs(b.type,"contextmenu"))l="contextmenu";else if(j.eqs(b.type,"click"))if(j.eqs(a.tagName,"span")&&a.getAttribute("treeNode"+f.id.SWITCH)!==null)d=j.getNodeMainDom(a).id, +g="switchNode";else{if(k=j.getMDom(c,a,[{tagName:"a",attrName:"treeNode"+f.id.A}]))d=j.getNodeMainDom(k).id,g="clickNode"}else if(j.eqs(b.type,"dblclick")&&(l="dblclick",k=j.getMDom(c,a,[{tagName:"a",attrName:"treeNode"+f.id.A}])))d=j.getNodeMainDom(k).id,g="switchNode";if(l.length>0&&d.length==0&&(k=j.getMDom(c,a,[{tagName:"a",attrName:"treeNode"+f.id.A}])))d=j.getNodeMainDom(k).id;if(d.length>0)switch(e=h.getNodeCache(c,d),g){case "switchNode":e.isParent?j.eqs(b.type,"click")||j.eqs(b.type,"dblclick")&& +j.apply(c.view.dblClickExpand,[c.treeId,e],c.view.dblClickExpand)?i=H:g="":g="";break;case "clickNode":i=I}switch(l){case "mousedown":n=J;break;case "mouseup":n=K;break;case "dblclick":n=L;break;case "contextmenu":n=M}return{stop:!1,node:e,nodeEventType:g,nodeEventCallback:i,treeEventType:l,treeEventCallback:n}}],B=[function(b){var a=h.getRoot(b);a||(a={},h.setRoot(b,a));a[b.data.key.children]=[];a.expandTriggerFlag=!1;a.curSelectedList=[];a.noSelection=!0;a.createdNodes=[];a.zId=0;a._ver=(new Date).getTime()}], +C=[],D=[],E=[],F=[],G=[],h={addNodeCache:function(b,a){h.getCache(b).nodes[h.getNodeCacheId(a.tId)]=a},getNodeCacheId:function(b){return b.substring(b.lastIndexOf("_")+1)},addAfterA:function(b){D.push(b)},addBeforeA:function(b){C.push(b)},addInnerAfterA:function(b){F.push(b)},addInnerBeforeA:function(b){E.push(b)},addInitBind:function(b){x.push(b)},addInitUnBind:function(b){y.push(b)},addInitCache:function(b){z.push(b)},addInitNode:function(b){A.push(b)},addInitProxy:function(b,a){a?t.splice(0,0, +b):t.push(b)},addInitRoot:function(b){B.push(b)},addNodesData:function(b,a,c,d){var e=b.data.key.children;a[e]?c>=a[e].length&&(c=-1):(a[e]=[],c=-1);if(a[e].length>0&&c===0)a[e][0].isFirstNode=!1,i.setNodeLineIcos(b,a[e][0]);else if(a[e].length>0&&c<0)a[e][a[e].length-1].isLastNode=!1,i.setNodeLineIcos(b,a[e][a[e].length-1]);a.isParent=!0;c<0?a[e]=a[e].concat(d):(b=[c,0].concat(d),a[e].splice.apply(a[e],b))},addSelectedNode:function(b,a){var c=h.getRoot(b);h.isSelectedNode(b,a)||c.curSelectedList.push(a)}, +addCreatedNode:function(b,a){(b.callback.onNodeCreated||b.view.addDiyDom)&&h.getRoot(b).createdNodes.push(a)},addZTreeTools:function(b){G.push(b)},exSetting:function(b){q.extend(!0,N,b)},fixPIdKeyValue:function(b,a){b.data.simpleData.enable&&(a[b.data.simpleData.pIdKey]=a.parentTId?a.getParentNode()[b.data.simpleData.idKey]:b.data.simpleData.rootPId)},getAfterA:function(b,a,c){for(var d=0,e=D.length;d-1&&g.push(a[l]),g=g.concat(h.getNodesByParamFuzzy(b,a[l][e],c,d));return g},getNodesByFilter:function(b,a,c,d,e){if(!a)return d?null:[];for(var g=b.data.key.children,f=d?null:[],i=0,n=a.length;i0)},clone:function(b){if(b===null)return null;var a=j.isArray(b)?[]:{},c;for(c in b)a[c]=b[c]instanceof Date?new Date(b[c].getTime()):typeof b[c]==="object"?j.clone(b[c]):b[c];return a},eqs:function(b,a){return b.toLowerCase()===a.toLowerCase()},isArray:function(b){return Object.prototype.toString.apply(b)=== +"[object Array]"},$:function(b,a,c){a&&typeof a!="string"&&(c=a,a="");return typeof b=="string"?q(b,c?c.treeObj.get(0).ownerDocument:null):q("#"+b.tId+a,c?c.treeObj:null)},getMDom:function(b,a,c){if(!a)return null;for(;a&&a.id!==b.treeId;){for(var d=0,e=c.length;a.tagName&&d0},uCanDo:function(){return!0}},i={addNodes:function(b,a,c,d,e){if(!b.data.keep.leaf||!a||a.isParent)if(j.isArray(d)||(d=[d]),b.data.simpleData.enable&&(d=h.transformTozTreeFormat(b,d)),a){var g=k(a,f.id.SWITCH,b),l=k(a,f.id.ICON,b),p=k(a,f.id.UL,b);if(!a.open)i.replaceSwitchClass(a,g,f.folder.CLOSE),i.replaceIcoClass(a,l,f.folder.CLOSE),a.open=!1,p.css({display:"none"});h.addNodesData(b,a,c,d);i.createNodes(b,a.level+1,d,a,c);e||i.expandCollapseParentNode(b,a, +!0)}else h.addNodesData(b,h.getRoot(b),c,d),i.createNodes(b,0,d,null,c)},appendNodes:function(b,a,c,d,e,g,f){if(!c)return[];var j=[],n=b.data.key.children,k=(d?d:h.getRoot(b))[n],m,Q;if(!k||e>=k.length)e=-1;for(var s=0,R=c.length;s0&&(m=i.appendNodes(b,a+1,o[n],o,-1,g,f&&o.open));f&&(i.makeDOMNodeMainBefore(j,b,o),i.makeDOMNodeLine(j,b,o),h.getBeforeA(b, +o,j),i.makeDOMNodeNameBefore(j,b,o),h.getInnerBeforeA(b,o,j),i.makeDOMNodeIcon(j,b,o),h.getInnerAfterA(b,o,j),i.makeDOMNodeNameAfter(j,b,o),h.getAfterA(b,o,j),o.isParent&&o.open&&i.makeUlHtml(b,o,j,m.join("")),i.makeDOMNodeMainAfter(j,b,o),h.addCreatedNode(b,o))}return j},appendParentULDom:function(b,a){var c=[],d=k(a,b);!d.get(0)&&a.parentTId&&(i.appendParentULDom(b,a.getParentNode()),d=k(a,b));var e=k(a,f.id.UL,b);e.get(0)&&e.remove();e=i.appendNodes(b,a.level+1,a[b.data.key.children],a,-1,!1,!0); +i.makeUlHtml(b,a,c,e.join(""));d.append(c.join(""))},asyncNode:function(b,a,c,d){var e,g;if(a&&!a.isParent)return j.apply(d),!1;else if(a&&a.isAjaxing)return!1;else if(j.apply(b.callback.beforeAsync,[b.treeId,a],!0)==!1)return j.apply(d),!1;if(a)a.isAjaxing=!0,k(a,f.id.ICON,b).attr({style:"","class":f.className.BUTTON+" "+f.className.ICO_LOADING});var l={};for(e=0,g=b.async.autoParam.length;a&&e1&&(n=p[1],p=p[0]);l[n]=a[p]}if(j.isArray(b.async.otherParam))for(e= +0,g=b.async.otherParam.length;e-1?JSON.stringify(l):l,dataType:b.async.dataType,success:function(e){if(P==h.getRoot(b)._ver){var g=[];try{g=!e||e.length==0?[]:typeof e=="string"?eval("("+ +e+")"):e}catch(l){g=e}if(a)a.isAjaxing=null,a.zAsync=!0;i.setNodeLineIcos(b,a);g&&g!==""?(g=j.apply(b.async.dataFilter,[b.treeId,a,g],g),i.addNodes(b,a,-1,g?j.clone(g):[],!!c)):i.addNodes(b,a,-1,[],!!c);b.treeObj.trigger(f.event.ASYNC_SUCCESS,[b.treeId,a,e]);j.apply(d)}},error:function(c,d,e){if(P==h.getRoot(b)._ver){if(a)a.isAjaxing=null;i.setNodeLineIcos(b,a);b.treeObj.trigger(f.event.ASYNC_ERROR,[b.treeId,a,c,d,e])}}});return!0},cancelPreSelectedNode:function(b,a,c){var d=h.getRoot(b).curSelectedList, +e,g;for(e=d.length-1;e>=0;e--)if(g=d[e],a===g||!a&&(!c||c!==g))if(k(g,f.id.A,b).removeClass(f.node.CURSELECTED),a){h.removeSelectedNode(b,a);break}else d.splice(e,1),b.treeObj.trigger(f.event.UNSELECTED,[b.treeId,g])},createNodeCallback:function(b){if(b.callback.onNodeCreated||b.view.addDiyDom)for(var a=h.getRoot(b);a.createdNodes.length>0;){var c=a.createdNodes.shift();j.apply(b.view.addDiyDom,[b.treeId,c]);b.callback.onNodeCreated&&b.treeObj.trigger(f.event.NODECREATED,[b.treeId,c])}},createNodes:function(b, +a,c,d,e){if(c&&c.length!=0){var g=h.getRoot(b),l=b.data.key.children,l=!d||d.open||!!k(d[l][0],b).get(0);g.createdNodes=[];var a=i.appendNodes(b,a,c,d,e,!0,l),j,n;d?(d=k(d,f.id.UL,b),d.get(0)&&(j=d)):j=b.treeObj;j&&(e>=0&&(n=j.children()[e]),e>=0&&n?q(n).before(a.join("")):j.append(a.join("")));i.createNodeCallback(b)}},destroy:function(b){b&&(h.initCache(b),h.initRoot(b),m.unbindTree(b),m.unbindEvent(b),b.treeObj.empty(),delete r[b.treeId])},expandCollapseNode:function(b,a,c,d,e){var g=h.getRoot(b), +l=b.data.key.children,p;if(a){if(g.expandTriggerFlag)p=e,e=function(){p&&p();a.open?b.treeObj.trigger(f.event.EXPAND,[b.treeId,a]):b.treeObj.trigger(f.event.COLLAPSE,[b.treeId,a])},g.expandTriggerFlag=!1;if(!a.open&&a.isParent&&(!k(a,f.id.UL,b).get(0)||a[l]&&a[l].length>0&&!k(a[l][0],b).get(0)))i.appendParentULDom(b,a),i.createNodeCallback(b);if(a.open==c)j.apply(e,[]);else{var c=k(a,f.id.UL,b),g=k(a,f.id.SWITCH,b),n=k(a,f.id.ICON,b);a.isParent?(a.open=!a.open,a.iconOpen&&a.iconClose&&n.attr("style", +i.makeNodeIcoStyle(b,a)),a.open?(i.replaceSwitchClass(a,g,f.folder.OPEN),i.replaceIcoClass(a,n,f.folder.OPEN),d==!1||b.view.expandSpeed==""?(c.show(),j.apply(e,[])):a[l]&&a[l].length>0?c.slideDown(b.view.expandSpeed,e):(c.show(),j.apply(e,[]))):(i.replaceSwitchClass(a,g,f.folder.CLOSE),i.replaceIcoClass(a,n,f.folder.CLOSE),d==!1||b.view.expandSpeed==""||!(a[l]&&a[l].length>0)?(c.hide(),j.apply(e,[])):c.slideUp(b.view.expandSpeed,e))):j.apply(e,[])}}else j.apply(e,[])},expandCollapseParentNode:function(b, +a,c,d,e){a&&(a.parentTId?(i.expandCollapseNode(b,a,c,d),a.parentTId&&i.expandCollapseParentNode(b,a.getParentNode(),c,d,e)):i.expandCollapseNode(b,a,c,d,e))},expandCollapseSonNode:function(b,a,c,d,e){var g=h.getRoot(b),f=b.data.key.children,g=a?a[f]:g[f],f=a?!1:d,j=h.getRoot(b).expandTriggerFlag;h.getRoot(b).expandTriggerFlag=!1;if(g)for(var k=0,m=g.length;k=0;d--)if(a===c[d])return!0;return!1},makeDOMNodeIcon:function(b,a,c){var d=h.getNodeName(a,c),d=a.view.nameIsHTML?d:d.replace(/&/g,"&").replace(//g,">");b.push("",d,"")},makeDOMNodeLine:function(b, +a,c){b.push("")},makeDOMNodeMainAfter:function(b){b.push("")},makeDOMNodeMainBefore:function(b,a,c){b.push("
  • ")},makeDOMNodeNameAfter:function(b){b.push("")},makeDOMNodeNameBefore:function(b,a,c){var d=h.getNodeTitle(a,c),e=i.makeNodeUrl(a,c),g=i.makeNodeFontCss(a,c),l=[],k;for(k in g)l.push(k, +":",g[k],";");b.push("0?"href='"+e+"'":""," target='",i.makeNodeTarget(c),"' style='",l.join(""),"'");j.apply(a.view.showTitle,[a.treeId,c],a.view.showTitle)&&d&&b.push("title='",d.replace(/'/g,"'").replace(//g,">"),"'");b.push(">")},makeNodeFontCss:function(b,a){var c=j.apply(b.view.fontCss,[b.treeId,a],b.view.fontCss);return c&&typeof c!="function"? +c:{}},makeNodeIcoClass:function(b,a){var c=["ico"];a.isAjaxing||(c[0]=(a.iconSkin?a.iconSkin+"_":"")+c[0],a.isParent?c.push(a.open?f.folder.OPEN:f.folder.CLOSE):c.push(f.folder.DOCU));return f.className.BUTTON+" "+c.join("_")},makeNodeIcoStyle:function(b,a){var c=[];if(!a.isAjaxing){var d=a.isParent&&a.iconOpen&&a.iconClose?a.open?a.iconOpen:a.iconClose:a[b.data.key.icon];d&&c.push("background:url(",d,") 0 0 no-repeat;");(b.view.showIcon==!1||!j.apply(b.view.showIcon,[b.treeId,a],!0))&&c.push("width:0px;height:0px;")}return c.join("")}, +makeNodeLineClass:function(b,a){var c=[];b.view.showLine?a.level==0&&a.isFirstNode&&a.isLastNode?c.push(f.line.ROOT):a.level==0&&a.isFirstNode?c.push(f.line.ROOTS):a.isLastNode?c.push(f.line.BOTTOM):c.push(f.line.CENTER):c.push(f.line.NOLINE);a.isParent?c.push(a.open?f.folder.OPEN:f.folder.CLOSE):c.push(f.folder.DOCU);return i.makeNodeLineClassEx(a)+c.join("_")},makeNodeLineClassEx:function(b){return f.className.BUTTON+" "+f.className.LEVEL+b.level+" "+f.className.SWITCH+" "},makeNodeTarget:function(b){return b.target|| +"_blank"},makeNodeUrl:function(b,a){var c=b.data.key.url;return a[c]?a[c]:null},makeUlHtml:function(b,a,c,d){c.push("
      ");c.push(d);c.push("
    ")},makeUlLineClass:function(b,a){return b.view.showLine&&!a.isLastNode?f.line.LINE:""},removeChildNodes:function(b,a){if(a){var c=b.data.key.children,d=a[c];if(d){for(var e=0,g=d.length;e0)a[c][0].isFirstNode=!0},setLastNode:function(b,a){var c=b.data.key.children,d=a[c].length;if(d>0)a[c][d-1].isLastNode=!0},removeNode:function(b,a){var c=h.getRoot(b),d=b.data.key.children,e=a.parentTId?a.getParentNode():c;a.isFirstNode=!1;a.isLastNode=!1;a.getPreNode=function(){return null};a.getNextNode=function(){return null};if(h.getNodeCache(b,a.tId)){k(a,b).remove();h.removeNodeCache(b,a);h.removeSelectedNode(b,a);for(var g=0,j=e[d].length;g0){var n=e[d][g-1],g=k(n,f.id.UL,b),j=k(n,f.id.SWITCH,b);p=k(n,f.id.ICON,b);e==c?e[d].length==1?i.replaceSwitchClass(n,j,f.line.ROOT):(c=k(e[d][0],f.id.SWITCH,b),i.replaceSwitchClass(e[d][0],c,f.line.ROOTS), +i.replaceSwitchClass(n,j,f.line.BOTTOM)):i.replaceSwitchClass(n,j,f.line.BOTTOM);g.removeClass(f.line.LINE)}}},replaceIcoClass:function(b,a,c){if(a&&!b.isAjaxing&&(b=a.attr("class"),b!=void 0)){b=b.split("_");switch(c){case f.folder.OPEN:case f.folder.CLOSE:case f.folder.DOCU:b[b.length-1]=c}a.attr("class",b.join("_"))}},replaceSwitchClass:function(b,a,c){if(a){var d=a.attr("class");if(d!=void 0){d=d.split("_");switch(c){case f.line.ROOT:case f.line.ROOTS:case f.line.CENTER:case f.line.BOTTOM:case f.line.NOLINE:d[0]= +i.makeNodeLineClassEx(b)+c;break;case f.folder.OPEN:case f.folder.CLOSE:case f.folder.DOCU:d[1]=c}a.attr("class",d.join("_"));c!==f.folder.DOCU?a.removeAttr("disabled"):a.attr("disabled","disabled")}}},selectNode:function(b,a,c){c||i.cancelPreSelectedNode(b,null,a);k(a,f.id.A,b).addClass(f.node.CURSELECTED);h.addSelectedNode(b,a);b.treeObj.trigger(f.event.SELECTED,[b.treeId,a])},setNodeFontCss:function(b,a){var c=k(a,f.id.A,b),d=i.makeNodeFontCss(b,a);d&&c.css(d)},setNodeLineIcos:function(b,a){if(a){var c= +k(a,f.id.SWITCH,b),d=k(a,f.id.UL,b),e=k(a,f.id.ICON,b),g=i.makeUlLineClass(b,a);g.length==0?d.removeClass(f.line.LINE):d.addClass(g);c.attr("class",i.makeNodeLineClass(b,a));a.isParent?c.removeAttr("disabled"):c.attr("disabled","disabled");e.removeAttr("style");e.attr("style",i.makeNodeIcoStyle(b,a));e.attr("class",i.makeNodeIcoClass(b,a))}},setNodeName:function(b,a){var c=h.getNodeTitle(b,a),d=k(a,f.id.SPAN,b);d.empty();b.view.nameIsHTML?d.html(h.getNodeName(b,a)):d.text(h.getNodeName(b,a));j.apply(b.view.showTitle, +[b.treeId,a],b.view.showTitle)&&k(a,f.id.A,b).attr("title",!c?"":c)},setNodeTarget:function(b,a){k(a,f.id.A,b).attr("target",i.makeNodeTarget(a))},setNodeUrl:function(b,a){var c=k(a,f.id.A,b),d=i.makeNodeUrl(b,a);d==null||d.length==0?c.removeAttr("href"):c.attr("href",d)},switchNode:function(b,a){a.open||!j.canAsync(b,a)?i.expandCollapseNode(b,a,!a.open):b.async.enable?i.asyncNode(b,a)||i.expandCollapseNode(b,a,!a.open):a&&i.expandCollapseNode(b,a,!a.open)}};q.fn.zTree={consts:{className:{BUTTON:"button", +LEVEL:"level",ICO_LOADING:"ico_loading",SWITCH:"switch",NAME:"node_name"},event:{NODECREATED:"ztree_nodeCreated",CLICK:"ztree_click",EXPAND:"ztree_expand",COLLAPSE:"ztree_collapse",ASYNC_SUCCESS:"ztree_async_success",ASYNC_ERROR:"ztree_async_error",REMOVE:"ztree_remove",SELECTED:"ztree_selected",UNSELECTED:"ztree_unselected"},id:{A:"_a",ICON:"_ico",SPAN:"_span",SWITCH:"_switch",UL:"_ul"},line:{ROOT:"root",ROOTS:"roots",CENTER:"center",BOTTOM:"bottom",NOLINE:"noline",LINE:"line"},folder:{OPEN:"open", +CLOSE:"close",DOCU:"docu"},node:{CURSELECTED:"curSelectedNode"}},_z:{tools:j,view:i,event:m,data:h},getZTreeObj:function(b){return(b=h.getZTreeTools(b))?b:null},destroy:function(b){if(b&&b.length>0)i.destroy(h.getSetting(b));else for(var a in r)i.destroy(r[a])},init:function(b,a,c){var d=j.clone(N);q.extend(!0,d,a);d.treeId=b.attr("id");d.treeObj=b;d.treeObj.empty();r[d.treeId]=d;if(typeof document.body.style.maxHeight==="undefined")d.view.expandSpeed="";h.initRoot(d);b=h.getRoot(d);a=d.data.key.children; +c=c?j.clone(j.isArray(c)?c:[c]):[];b[a]=d.data.simpleData.enable?h.transformTozTreeFormat(d,c):c;h.initCache(d);m.unbindTree(d);m.bindTree(d);m.unbindEvent(d);m.bindEvent(d);c={setting:d,addNodes:function(a,b,c,f){function h(){i.addNodes(d,a,b,m,f==!0)}a||(a=null);if(a&&!a.isParent&&d.data.keep.leaf)return null;var k=parseInt(b,10);isNaN(k)?(f=!!c,c=b,b=-1):b=k;if(!c)return null;var m=j.clone(j.isArray(c)?c:[c]);j.canAsync(d,a)?i.asyncNode(d,a,f,h):h();return m},cancelSelectedNode:function(a){i.cancelPreSelectedNode(d, +a)},destroy:function(){i.destroy(d)},expandAll:function(a){a=!!a;i.expandCollapseSonNode(d,null,a,!0);return a},expandNode:function(a,b,c,f,n){function m(){var b=k(a,d).get(0);b&&f!==!1&&i.scrollIntoView(b)}if(!a||!a.isParent)return null;b!==!0&&b!==!1&&(b=!a.open);if((n=!!n)&&b&&j.apply(d.callback.beforeExpand,[d.treeId,a],!0)==!1)return null;else if(n&&!b&&j.apply(d.callback.beforeCollapse,[d.treeId,a],!0)==!1)return null;b&&a.parentTId&&i.expandCollapseParentNode(d,a.getParentNode(),b,!1);if(b=== +a.open&&!c)return null;h.getRoot(d).expandTriggerFlag=n;!j.canAsync(d,a)&&c?i.expandCollapseSonNode(d,a,b,!0,m):(a.open=!b,i.switchNode(this.setting,a),m());return b},getNodes:function(){return h.getNodes(d)},getNodeByParam:function(a,b,c){return!a?null:h.getNodeByParam(d,c?c[d.data.key.children]:h.getNodes(d),a,b)},getNodeByTId:function(a){return h.getNodeCache(d,a)},getNodesByParam:function(a,b,c){return!a?null:h.getNodesByParam(d,c?c[d.data.key.children]:h.getNodes(d),a,b)},getNodesByParamFuzzy:function(a, +b,c){return!a?null:h.getNodesByParamFuzzy(d,c?c[d.data.key.children]:h.getNodes(d),a,b)},getNodesByFilter:function(a,b,c,f){b=!!b;return!a||typeof a!="function"?b?null:[]:h.getNodesByFilter(d,c?c[d.data.key.children]:h.getNodes(d),a,b,f)},getNodeIndex:function(a){if(!a)return null;for(var b=d.data.key.children,c=a.parentTId?a.getParentNode():h.getRoot(d),f=0,i=c[b].length;f0?i.createNodes(d,0,b[a],null,-1):d.async.enable&&d.async.url&&d.async.url!==""&&i.asyncNode(d);return c}};var O=q.fn.zTree,k=j.$,f=O.consts})(jQuery); + +/* + * JQuery zTree excheck v3.5.26 + * http://zTree.me/ + * + * Copyright (c) 2010 Hunter.z + * + * Licensed same as jquery - MIT License + * http://www.opensource.org/licenses/mit-license.php + * + * email: hunter.z@263.net + * Date: 2016-11-03 + */ +(function(m){var p,q,r,o={event:{CHECK:"ztree_check"},id:{CHECK:"_check"},checkbox:{STYLE:"checkbox",DEFAULT:"chk",DISABLED:"disable",FALSE:"false",TRUE:"true",FULL:"full",PART:"part",FOCUS:"focus"},radio:{STYLE:"radio",TYPE_ALL:"all",TYPE_LEVEL:"level"}},v={check:{enable:!1,autoCheckTrigger:!1,chkStyle:o.checkbox.STYLE,nocheckInherit:!1,chkDisabledInherit:!1,radioType:o.radio.TYPE_LEVEL,chkboxType:{Y:"ps",N:"ps"}},data:{key:{checked:"checked"}},callback:{beforeCheck:null,onCheck:null}};p=function(c, +a){if(a.chkDisabled===!0)return!1;var b=g.getSetting(c.data.treeId),d=b.data.key.checked;if(k.apply(b.callback.beforeCheck,[b.treeId,a],!0)==!1)return!0;a[d]=!a[d];e.checkNodeRelation(b,a);d=n(a,j.id.CHECK,b);e.setChkClass(b,d,a);e.repairParentChkClassWithSelf(b,a);b.treeObj.trigger(j.event.CHECK,[c,b.treeId,a]);return!0};q=function(c,a){if(a.chkDisabled===!0)return!1;var b=g.getSetting(c.data.treeId),d=n(a,j.id.CHECK,b);a.check_Focus=!0;e.setChkClass(b,d,a);return!0};r=function(c,a){if(a.chkDisabled=== +!0)return!1;var b=g.getSetting(c.data.treeId),d=n(a,j.id.CHECK,b);a.check_Focus=!1;e.setChkClass(b,d,a);return!0};m.extend(!0,m.fn.zTree.consts,o);m.extend(!0,m.fn.zTree._z,{tools:{},view:{checkNodeRelation:function(c,a){var b,d,h,i=c.data.key.children,l=c.data.key.checked;b=j.radio;if(c.check.chkStyle==b.STYLE){var f=g.getRadioCheckedList(c);if(a[l])if(c.check.radioType==b.TYPE_ALL){for(d=f.length-1;d>=0;d--)b=f[d],b[l]&&b!=a&&(b[l]=!1,f.splice(d,1),e.setChkClass(c,n(b,j.id.CHECK,c),b),b.parentTId!= +a.parentTId&&e.repairParentChkClassWithSelf(c,b));f.push(a)}else{f=a.parentTId?a.getParentNode():g.getRoot(c);for(d=0,h=f[i].length;d-1)&&e.setSonNodeCheckBox(c,a,!0),!a[l]&&(!a[i]||a[i].length==0||c.check.chkboxType.N.indexOf("s")>-1)&&e.setSonNodeCheckBox(c, +a,!1),a[l]&&c.check.chkboxType.Y.indexOf("p")>-1&&e.setParentNodeCheckBox(c,a,!0),!a[l]&&c.check.chkboxType.N.indexOf("p")>-1&&e.setParentNodeCheckBox(c,a,!1)},makeChkClass:function(c,a){var b=c.data.key.checked,d=j.checkbox,h=j.radio,i="",i=a.chkDisabled===!0?d.DISABLED:a.halfCheck?d.PART:c.check.chkStyle==h.STYLE?a.check_Child_State<1?d.FULL:d.PART:a[b]?a.check_Child_State===2||a.check_Child_State===-1?d.FULL:d.PART:a.check_Child_State<1?d.FULL:d.PART,b=c.check.chkStyle+"_"+(a[b]?d.TRUE:d.FALSE)+ +"_"+i,b=a.check_Focus&&a.chkDisabled!==!0?b+"_"+d.FOCUS:b;return j.className.BUTTON+" "+d.DEFAULT+" "+b},repairAllChk:function(c,a){if(c.check.enable&&c.check.chkStyle===j.checkbox.STYLE)for(var b=c.data.key.checked,d=c.data.key.children,h=g.getRoot(c),i=0,l=h[d].length;i0?e.repairParentChkClass(c,a[b][0]):e.repairParentChkClass(c,a)}},repairSonChkDisabled:function(c,a,b,d){if(a){var h=c.data.key.children;if(a.chkDisabled!=b)a.chkDisabled=b;e.repairChkClass(c,a);if(a[h]&&d)for(var i=0,l=a[h].length;i0){l=!1;break}l&&e.setParentNodeCheckBox(c,a.getParentNode(),b,d)}},setSonNodeCheckBox:function(c,a,b,d){if(a){var h=c.data.key.children,i=c.data.key.checked,l=n(a,j.id.CHECK,c);d||(d=a);var f=!1;if(a[h])for(var k=0,m=a[h].length;k0?b?2:0:-1}else a.check_Child_State=-1;e.setChkClass(c,l,a);c.check.autoCheckTrigger&&a!=d&&a.nocheck!==!0&&a.chkDisabled!==!0&&c.treeObj.trigger(j.event.CHECK,[null,c.treeId,a])}}}},event:{},data:{getRadioCheckedList:function(c){for(var a=g.getRoot(c).radioCheckedList,b=0,d=a.length;b-1&&a.check_Child_State<2:a.check_Child_State>0}},getTreeCheckedNodes:function(c,a,b,d){if(!a)return[];for(var h=c.data.key.children,i=c.data.key.checked,e=b&&c.check.chkStyle==j.radio.STYLE&&c.check.radioType==j.radio.TYPE_ALL,d=!d?[]:d, +f=0,k=a.length;f0)break}return d},getTreeChangeCheckedNodes:function(c,a,b){if(!a)return[];for(var d=c.data.key.children,h=c.data.key.checked,b=!b?[]:b,i=0,e=a.length;i0?2:0,g==2){h=2;break}else g==0&&(h=0);else if(c.check.chkStyle==j.checkbox.STYLE)if(g=f.nocheck===!0||f.chkDisabled===!0?f.check_Child_State:f.halfCheck===!0?1:f[d]?f.check_Child_State===-1||f.check_Child_State===2?2:1:f.check_Child_State>0?1:0,g===1){h=1;break}else if(g=== +2&&h>-1&&i>0&&g!==h){h=1;break}else if(h===2&&g>-1&&g<2){h=1;break}else g>-1&&(h=g)}a.check_Child_State=h}}}});var m=m.fn.zTree,k=m._z.tools,j=m.consts,e=m._z.view,g=m._z.data,n=k.$;g.exSetting(v);g.addInitBind(function(c){c.treeObj.bind(j.event.CHECK,function(a,b,d,h){a.srcEvent=b;k.apply(c.callback.onCheck,[a,d,h])})});g.addInitUnBind(function(c){c.treeObj.unbind(j.event.CHECK)});g.addInitCache(function(){});g.addInitNode(function(c,a,b,d){if(b){a=c.data.key.checked;typeof b[a]=="string"&&(b[a]= +k.eqs(b[a],"true"));b[a]=!!b[a];b.checkedOld=b[a];if(typeof b.nocheck=="string")b.nocheck=k.eqs(b.nocheck,"true");b.nocheck=!!b.nocheck||c.check.nocheckInherit&&d&&!!d.nocheck;if(typeof b.chkDisabled=="string")b.chkDisabled=k.eqs(b.chkDisabled,"true");b.chkDisabled=!!b.chkDisabled||c.check.chkDisabledInherit&&d&&!!d.chkDisabled;if(typeof b.halfCheck=="string")b.halfCheck=k.eqs(b.halfCheck,"true");b.halfCheck=!!b.halfCheck;b.check_Child_State=-1;b.check_Focus=!1;b.getCheckStatus=function(){return g.getCheckStatus(c, +b)};c.check.chkStyle==j.radio.STYLE&&c.check.radioType==j.radio.TYPE_ALL&&b[a]&&g.getRoot(c).radioCheckedList.push(b)}});g.addInitProxy(function(c){var a=c.target,b=g.getSetting(c.data.treeId),d="",h=null,e="",l=null;if(k.eqs(c.type,"mouseover")){if(b.check.enable&&k.eqs(a.tagName,"span")&&a.getAttribute("treeNode"+j.id.CHECK)!==null)d=k.getNodeMainDom(a).id,e="mouseoverCheck"}else if(k.eqs(c.type,"mouseout")){if(b.check.enable&&k.eqs(a.tagName,"span")&&a.getAttribute("treeNode"+j.id.CHECK)!==null)d= +k.getNodeMainDom(a).id,e="mouseoutCheck"}else if(k.eqs(c.type,"click")&&b.check.enable&&k.eqs(a.tagName,"span")&&a.getAttribute("treeNode"+j.id.CHECK)!==null)d=k.getNodeMainDom(a).id,e="checkNode";if(d.length>0)switch(h=g.getNodeCache(b,d),e){case "checkNode":l=p;break;case "mouseoverCheck":l=q;break;case "mouseoutCheck":l=r}return{stop:e==="checkNode",node:h,nodeEventType:e,nodeEventCallback:l,treeEventType:"",treeEventCallback:null}},!0);g.addInitRoot(function(c){g.getRoot(c).radioCheckedList=[]}); +g.addBeforeA(function(c,a,b){c.check.enable&&(g.makeChkFlag(c,a),b.push(""))});g.addZTreeTools(function(c,a){a.checkNode=function(a,b,c,g){var f=this.setting.data.key.checked;if(a.chkDisabled!==!0&&(b!==!0&&b!==!1&&(b=!a[f]),g=!!g,(a[f]!==b||c)&&!(g&&k.apply(this.setting.callback.beforeCheck,[this.setting.treeId,a],!0)==!1)&&k.uCanDo(this.setting)&&this.setting.check.enable&& +a.nocheck!==!0))a[f]=b,b=n(a,j.id.CHECK,this.setting),(c||this.setting.check.chkStyle===j.radio.STYLE)&&e.checkNodeRelation(this.setting,a),e.setChkClass(this.setting,b,a),e.repairParentChkClassWithSelf(this.setting,a),g&&this.setting.treeObj.trigger(j.event.CHECK,[null,this.setting.treeId,a])};a.checkAllNodes=function(a){e.repairAllChk(this.setting,!!a)};a.getCheckedNodes=function(a){var b=this.setting.data.key.children;return g.getTreeCheckedNodes(this.setting,g.getRoot(this.setting)[b],a!==!1)}; +a.getChangeCheckedNodes=function(){var a=this.setting.data.key.children;return g.getTreeChangeCheckedNodes(this.setting,g.getRoot(this.setting)[a])};a.setChkDisabled=function(a,b,c,g){b=!!b;c=!!c;e.repairSonChkDisabled(this.setting,a,b,!!g);e.repairParentChkDisabled(this.setting,a.getParentNode(),b,c)};var b=a.updateNode;a.updateNode=function(c,g){b&&b.apply(a,arguments);if(c&&this.setting.check.enable&&n(c,this.setting).get(0)&&k.uCanDo(this.setting)){var i=n(c,j.id.CHECK,this.setting);(g==!0||this.setting.check.chkStyle=== +j.radio.STYLE)&&e.checkNodeRelation(this.setting,c);e.setChkClass(this.setting,i,c);e.repairParentChkClassWithSelf(this.setting,c)}}});var s=e.createNodes;e.createNodes=function(c,a,b,d,g){s&&s.apply(e,arguments);b&&e.repairParentChkClassWithSelf(c,d)};var t=e.removeNode;e.removeNode=function(c,a){var b=a.getParentNode();t&&t.apply(e,arguments);a&&b&&(e.repairChkClass(c,b),e.repairParentChkClass(c,b))};var u=e.appendNodes;e.appendNodes=function(c,a,b,d,h,i,j){var f="";u&&(f=u.apply(e,arguments)); +d&&g.makeChkFlag(c,d);return f}})(jQuery); + +/* + * JQuery zTree exedit v3.5.26 + * http://zTree.me/ + * + * Copyright (c) 2010 Hunter.z + * + * Licensed same as jquery - MIT License + * http://www.opensource.org/licenses/mit-license.php + * + * email: hunter.z@263.net + * Date: 2016-11-03 + */ +(function(v){var J={event:{DRAG:"ztree_drag",DROP:"ztree_drop",RENAME:"ztree_rename",DRAGMOVE:"ztree_dragmove"},id:{EDIT:"_edit",INPUT:"_input",REMOVE:"_remove"},move:{TYPE_INNER:"inner",TYPE_PREV:"prev",TYPE_NEXT:"next"},node:{CURSELECTED_EDIT:"curSelectedNode_Edit",TMPTARGET_TREE:"tmpTargetzTree",TMPTARGET_NODE:"tmpTargetNode"}},x={onHoverOverNode:function(b,a){var c=m.getSetting(b.data.treeId),d=m.getRoot(c);if(d.curHoverNode!=a)x.onHoverOutNode(b);d.curHoverNode=a;f.addHoverDom(c,a)},onHoverOutNode:function(b){var b= +m.getSetting(b.data.treeId),a=m.getRoot(b);if(a.curHoverNode&&!m.isSelectedNode(b,a.curHoverNode))f.removeTreeDom(b,a.curHoverNode),a.curHoverNode=null},onMousedownNode:function(b,a){function c(b){if(B.dragFlag==0&&Math.abs(O-b.clientX)1){var j=l[0].parentTId?l[0].getParentNode()[i]:m.getNodes(e);i=[];for(a=0,c=j.length;a-1&&k+1!==a&&(n=!1),i.push(j[a]),k=a),l.length===i.length){l=i;break}}n&&(I=l[0].getPreNode(),R=l[l.length-1].getNextNode());D=o("
      ", +e);for(a=0,c=l.length;a0),f.removeTreeDom(e,n),a>e.edit.drag.maxShowNodeNum-1||(k=o("
    • ",e),k.append(o(n,d.id.A,e).clone()),k.css("padding","0"),k.children("#"+n.tId+d.id.A).removeClass(d.node.CURSELECTED),D.append(k),a==e.edit.drag.maxShowNodeNum-1&&(k=o("
    • ...
    • ",e),D.append(k)));D.attr("id",l[0].tId+d.id.UL+"_tmp");D.addClass(e.treeObj.attr("class"));D.appendTo(M);A=o("", +e);A.attr("id","zTreeMove_arrow_tmp");A.appendTo(M);e.treeObj.trigger(d.event.DRAG,[b,e.treeId,l])}if(B.dragFlag==1){s&&A.attr("id")==b.target.id&&u&&b.clientX+G.scrollLeft()+2>v("#"+u+d.id.A,s).offset().left?(n=v("#"+u+d.id.A,s),b.target=n.length>0?n.get(0):b.target):s&&(s.removeClass(d.node.TMPTARGET_TREE),u&&v("#"+u+d.id.A,s).removeClass(d.node.TMPTARGET_NODE+"_"+d.move.TYPE_PREV).removeClass(d.node.TMPTARGET_NODE+"_"+J.move.TYPE_NEXT).removeClass(d.node.TMPTARGET_NODE+"_"+J.move.TYPE_INNER)); +u=s=null;K=!1;h=e;n=m.getSettings();for(var y in n)if(n[y].treeId&&n[y].edit.enable&&n[y].treeId!=e.treeId&&(b.target.id==n[y].treeId||v(b.target).parents("#"+n[y].treeId).length>0))K=!0,h=n[y];y=G.scrollTop();k=G.scrollLeft();i=h.treeObj.offset();a=h.treeObj.get(0).scrollHeight;n=h.treeObj.get(0).scrollWidth;c=b.clientY+y-i.top;var p=h.treeObj.height()+i.top-b.clientY-y,q=b.clientX+k-i.left,H=h.treeObj.width()+i.left-b.clientX-k;i=ce.edit.drag.borderMin;var j=pe.edit.drag.borderMin,F=qe.edit.drag.borderMin,x=He.edit.drag.borderMin,p=c>e.edit.drag.borderMin&&p>e.edit.drag.borderMin&&q>e.edit.drag.borderMin&&H>e.edit.drag.borderMin,q=i&&h.treeObj.scrollTop()<=0,H=j&&h.treeObj.scrollTop()+h.treeObj.height()+10>=a,N=F&&h.treeObj.scrollLeft()<=0,Q=x&&h.treeObj.scrollLeft()+h.treeObj.width()+10>=n;if(b.target&&g.isChildOrSelf(b.target,h.treeId)){for(var E=b.target;E&&E.tagName&&!g.eqs(E.tagName,"li")&&E.id!= +h.treeId;)E=E.parentNode;var S=!0;for(a=0,c=l.length;a0){S=!1;break}if(S&&b.target&&g.isChildOrSelf(b.target,E.id+d.id.A))s=v(E),u=E.id}n=l[0];if(p&&g.isChildOrSelf(b.target,h.treeId)){if(!s&&(b.target.id==h.treeId||q||H||N||Q)&&(K||!K&&n.parentTId))s=h.treeObj;i?h.treeObj.scrollTop(h.treeObj.scrollTop()-10):j&&h.treeObj.scrollTop(h.treeObj.scrollTop()+10);F?h.treeObj.scrollLeft(h.treeObj.scrollLeft()-10):x&&h.treeObj.scrollLeft(h.treeObj.scrollLeft()+ +10);s&&s!=h.treeObj&&s.offset().left=-0.2)&&n?(a=1-A.width(),c=p-A.height()/2,w=d.move.TYPE_PREV):(N==0||y>=N&&y<=1.2)&&k?(a=1-A.width(),c=x==null||z.isParent&&z.open?p+F.height()-A.height()/2:x.offset().top-A.height()/2,w=d.move.TYPE_NEXT):i?(a=5-A.width(),c=p,w=d.move.TYPE_INNER):j(),s){A.css({display:"block",top:c+"px",left:q+a+"px"});F.addClass(d.node.TMPTARGET_NODE+"_"+w);if(T!=u||U!=w)L=(new Date).getTime();if(z&&z.isParent&&w==d.move.TYPE_INNER&& +(y=!0,window.zTreeMoveTimer&&window.zTreeMoveTargetNodeTId!==z.tId?(clearTimeout(window.zTreeMoveTimer),window.zTreeMoveTargetNodeTId=null):window.zTreeMoveTimer&&window.zTreeMoveTargetNodeTId===z.tId&&(y=!1),y))window.zTreeMoveTimer=setTimeout(function(){w==d.move.TYPE_INNER&&z&&z.isParent&&!z.open&&(new Date).getTime()-L>h.edit.drag.autoOpenTime&&g.apply(h.callback.beforeDragOpen,[h.treeId,z],!0)&&(f.switchNode(h,z),h.edit.drag.autoExpandTrigger&&h.treeObj.trigger(d.event.EXPAND,[h.treeId,z]))}, +h.edit.drag.autoOpenTime+50),window.zTreeMoveTargetNodeTId=z.tId}}else if(w=d.move.TYPE_INNER,s&&g.apply(h.edit.drag.inner,[h.treeId,l,null],!!h.edit.drag.inner)?s.addClass(d.node.TMPTARGET_TREE):s=null,A.css({display:"none"}),window.zTreeMoveTimer)clearTimeout(window.zTreeMoveTimer),window.zTreeMoveTargetNodeTId=null;T=u;U=w;e.treeObj.trigger(d.event.DRAGMOVE,[b,e.treeId,l])}return!1}function r(b){if(window.zTreeMoveTimer)clearTimeout(window.zTreeMoveTimer),window.zTreeMoveTargetNodeTId=null;U=T= +null;G.unbind("mousemove",c);G.unbind("mouseup",r);G.unbind("selectstart",k);M.css("cursor","auto");s&&(s.removeClass(d.node.TMPTARGET_TREE),u&&v("#"+u+d.id.A,s).removeClass(d.node.TMPTARGET_NODE+"_"+d.move.TYPE_PREV).removeClass(d.node.TMPTARGET_NODE+"_"+J.move.TYPE_NEXT).removeClass(d.node.TMPTARGET_NODE+"_"+J.move.TYPE_INNER));g.showIfameMask(e,!1);t.showHoverDom=!0;if(B.dragFlag!=0){B.dragFlag=0;var a,i,j;for(a=0,i=l.length;a0;)c.dragMaskList[0].remove(),c.dragMaskList.shift();if(a)for(var d=o("iframe",b),f=0,i=d.length;f",b);j.appendTo(o("body",b));c.dragMaskList.push(j)}}},view:{addEditBtn:function(b, +a){if(!(a.editNameFlag||o(a,d.id.EDIT,b).length>0)&&g.apply(b.edit.showRenameBtn,[b.treeId,a],b.edit.showRenameBtn)){var c=o(a,d.id.A,b),r="";c.append(r);o(a,d.id.EDIT,b).bind("click",function(){if(!g.uCanDo(b)||g.apply(b.callback.beforeEditName,[b.treeId,a],!0)==!1)return!1;f.editNode(b,a);return!1}).show()}}, +addRemoveBtn:function(b,a){if(!(a.editNameFlag||o(a,d.id.REMOVE,b).length>0)&&g.apply(b.edit.showRemoveBtn,[b.treeId,a],b.edit.showRemoveBtn)){var c=o(a,d.id.A,b),r="";c.append(r);o(a,d.id.REMOVE,b).bind("click",function(){if(!g.uCanDo(b)||g.apply(b.callback.beforeRemove,[b.treeId,a],!0)==!1)return!1;f.removeNode(b, +a);b.treeObj.trigger(d.event.REMOVE,[b.treeId,a]);return!1}).bind("mousedown",function(){return!0}).show()}},addHoverDom:function(b,a){if(m.getRoots().showHoverDom)a.isHover=!0,b.edit.enable&&(f.addEditBtn(b,a),f.addRemoveBtn(b,a)),g.apply(b.view.addHoverDom,[b.treeId,a])},cancelCurEditNode:function(b,a,c){var r=m.getRoot(b),k=b.data.key.name,i=r.curEditNode;if(i){var j=r.curEditInput,a=a?a:c?i[k]:j.val();if(g.apply(b.callback.beforeRename,[b.treeId,i,a,c],!0)===!1)return!1;i[k]=a;o(i,d.id.A,b).removeClass(d.node.CURSELECTED_EDIT); +j.unbind();f.setNodeName(b,i);i.editNameFlag=!1;r.curEditNode=null;r.curEditInput=null;f.selectNode(b,i,!1);b.treeObj.trigger(d.event.RENAME,[b.treeId,i,c])}return r.noSelection=!0},editNode:function(b,a){var c=m.getRoot(b);f.editNodeBlur=!1;if(m.isSelectedNode(b,a)&&c.curEditNode==a&&a.editNameFlag)setTimeout(function(){g.inputFocus(c.curEditInput)},0);else{var r=b.data.key.name;a.editNameFlag=!0;f.removeTreeDom(b,a);f.cancelCurEditNode(b);f.selectNode(b,a,!1);o(a,d.id.SPAN,b).html("");var k=o(a,d.id.INPUT,b);k.attr("value",a[r]);b.edit.editNameSelectAll?g.inputSelect(k):g.inputFocus(k);k.bind("blur",function(){f.editNodeBlur||f.cancelCurEditNode(b)}).bind("keydown",function(a){a.keyCode=="13"?(f.editNodeBlur=!0,f.cancelCurEditNode(b)):a.keyCode=="27"&&f.cancelCurEditNode(b,null,!0)}).bind("click",function(){return!1}).bind("dblclick",function(){return!1});o(a,d.id.A,b).addClass(d.node.CURSELECTED_EDIT);c.curEditInput=k;c.noSelection= +!1;c.curEditNode=a}},moveNode:function(b,a,c,r,k,i){var j=m.getRoot(b),e=b.data.key.children;if(a!=c&&(!b.data.keep.leaf||!a||a.isParent||r!=d.move.TYPE_INNER)){var g=c.parentTId?c.getParentNode():j,t=a===null||a==j;t&&a===null&&(a=j);if(t)r=d.move.TYPE_INNER;j=a.parentTId?a.getParentNode():j;if(r!=d.move.TYPE_PREV&&r!=d.move.TYPE_NEXT)r=d.move.TYPE_INNER;if(r==d.move.TYPE_INNER)if(t)c.parentTId=null;else{if(!a.isParent)a.isParent=!0,a.open=!!a.open,f.setNodeLineIcos(b,a);c.parentTId=a.tId}var p; +t?p=t=b.treeObj:(!i&&r==d.move.TYPE_INNER?f.expandCollapseNode(b,a,!0,!1):i||f.expandCollapseNode(b,a.getParentNode(),!0,!1),t=o(a,b),p=o(a,d.id.UL,b),t.get(0)&&!p.get(0)&&(p=[],f.makeUlHtml(b,a,p,""),t.append(p.join(""))),p=o(a,d.id.UL,b));var q=o(c,b);q.get(0)?t.get(0)||q.remove():q=f.appendNodes(b,c.level,[c],null,-1,!1,!0).join("");p.get(0)&&r==d.move.TYPE_INNER?p.append(q):t.get(0)&&r==d.move.TYPE_PREV?t.before(q):t.get(0)&&r==d.move.TYPE_NEXT&&t.after(q);var l=-1,v=0,x=null,t=null,D=c.level; +if(c.isFirstNode){if(l=0,g[e].length>1)x=g[e][1],x.isFirstNode=!0}else if(c.isLastNode)l=g[e].length-1,x=g[e][l-1],x.isLastNode=!0;else for(p=0,q=g[e].length;p=0&&g[e].splice(l,1);if(r!=d.move.TYPE_INNER)for(p=0,q=j[e].length;p0)t=a[e][a[e].length-1],t.isLastNode=!1;a[e].splice(a[e].length,0,c);c.isLastNode=!0;c.isFirstNode=a[e].length==1}else a.isFirstNode&&r==d.move.TYPE_PREV? +(j[e].splice(v,0,c),t=a,t.isFirstNode=!1,c.parentTId=a.parentTId,c.isFirstNode=!0,c.isLastNode=!1):a.isLastNode&&r==d.move.TYPE_NEXT?(j[e].splice(v+1,0,c),t=a,t.isLastNode=!1,c.parentTId=a.parentTId,c.isFirstNode=!1,c.isLastNode=!0):(r==d.move.TYPE_PREV?j[e].splice(v,0,c):j[e].splice(v+1,0,c),c.parentTId=a.parentTId,c.isFirstNode=!1,c.isLastNode=!1);m.fixPIdKeyValue(b,c);m.setSonNodeLevel(b,c.getParentNode(),c);f.setNodeLineIcos(b,c);f.repairNodeLevelClass(b,c,D);!b.data.keep.parent&&g[e].length< +1?(g.isParent=!1,g.open=!1,a=o(g,d.id.UL,b),r=o(g,d.id.SWITCH,b),e=o(g,d.id.ICON,b),f.replaceSwitchClass(g,r,d.folder.DOCU),f.replaceIcoClass(g,e,d.folder.DOCU),a.css("display","none")):x&&f.setNodeLineIcos(b,x);t&&f.setNodeLineIcos(b,t);b.check&&b.check.enable&&f.repairChkClass&&(f.repairChkClass(b,g),f.repairParentChkClassWithSelf(b,g),g!=c.parent&&f.repairParentChkClassWithSelf(b,c));i||f.expandCollapseParentNode(b,c.getParentNode(),!0,k)}},removeEditBtn:function(b,a){o(a,d.id.EDIT,b).unbind().remove()}, +removeRemoveBtn:function(b,a){o(a,d.id.REMOVE,b).unbind().remove()},removeTreeDom:function(b,a){a.isHover=!1;f.removeEditBtn(b,a);f.removeRemoveBtn(b,a);g.apply(b.view.removeHoverDom,[b.treeId,a])},repairNodeLevelClass:function(b,a,c){if(c!==a.level){var f=o(a,b),g=o(a,d.id.A,b),b=o(a,d.id.UL,b),c=d.className.LEVEL+c,a=d.className.LEVEL+a.level;f.removeClass(c);f.addClass(a);g.removeClass(c);g.addClass(a);b.removeClass(c);b.addClass(a)}},selectNodes:function(b,a){for(var c=0,d=a.length;c0)}},event:{},data:{setSonNodeLevel:function(b,a,c){if(c){var d=b.data.key.children;c.level=a?a.level+1:0;if(c[d])for(var a=0,f=c[d].length;a0)switch(i=m.getNodeCache(c,k),j){case "mousedownNode":e=x.onMousedownNode;break;case "hoverOverNode":e=x.onHoverOverNode;break;case "hoverOutNode":e= +x.onHoverOutNode}return{stop:!1,node:i,nodeEventType:j,nodeEventCallback:e,treeEventType:"",treeEventCallback:null}});m.addInitRoot(function(b){var b=m.getRoot(b),a=m.getRoots();b.curEditNode=null;b.curEditInput=null;b.curHoverNode=null;b.dragFlag=0;b.dragNodeShowBefore=[];b.dragMaskList=[];a.showHoverDom=!0});m.addZTreeTools(function(b,a){a.cancelEditName=function(a){m.getRoot(this.setting).curEditNode&&f.cancelCurEditNode(this.setting,a?a:null,!0)};a.copyNode=function(a,b,k,i){if(!b)return null; +if(a&&!a.isParent&&this.setting.data.keep.leaf&&k===d.move.TYPE_INNER)return null;var j=this,e=g.clone(b);if(!a)a=null,k=d.move.TYPE_INNER;k==d.move.TYPE_INNER?(b=function(){f.addNodes(j.setting,a,-1,[e],i)},g.canAsync(this.setting,a)?f.asyncNode(this.setting,a,i,b):b()):(f.addNodes(this.setting,a.parentNode,-1,[e],i),f.moveNode(this.setting,a,e,k,!1,i));return e};a.editName=function(a){a&&a.tId&&a===m.getNodeCache(this.setting,a.tId)&&(a.parentTId&&f.expandCollapseParentNode(this.setting,a.getParentNode(), +!0),f.editNode(this.setting,a))};a.moveNode=function(a,b,k,i){function j(){f.moveNode(e.setting,a,b,k,!1,i)}if(!b)return b;if(a&&!a.isParent&&this.setting.data.keep.leaf&&k===d.move.TYPE_INNER)return null;else if(a&&(b.parentTId==a.tId&&k==d.move.TYPE_INNER||o(b,this.setting).find("#"+a.tId).length>0))return null;else a||(a=null);var e=this;g.canAsync(this.setting,a)&&k===d.move.TYPE_INNER?f.asyncNode(this.setting,a,i,j):j();return b};a.setEditable=function(a){this.setting.edit.enable=a;return this.refresh()}}); +var O=f.cancelPreSelectedNode;f.cancelPreSelectedNode=function(b,a){for(var c=m.getRoot(b).curSelectedList,d=0,g=c.length;d + + + 文件上传 + + + + + + + + + + + + + + + + + + + +
      +
      + +
      +
      +
      +
      + + + \ No newline at end of file diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/views/index.html b/spring-boot-22-FarstPlus/src/main/resources/templates/views/index.html new file mode 100644 index 0000000..fb6d438 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/views/index.html @@ -0,0 +1,128 @@ + + + + + + + 快速开发平台(企业版) + + + + + + + + + + + + + + + +
      +
      + + + +
      + + + + + + + +
      + +
      + +
      + + +
      + +
      + +
      + + +
      + + Copyright © 2016 timebusker.top All Rights Reserved +
      + + +
      + +
      + + + + + + + + + + + + + + diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/views/login.html b/spring-boot-22-FarstPlus/src/main/resources/templates/views/login.html new file mode 100644 index 0000000..1cec477 --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/views/login.html @@ -0,0 +1,118 @@ + + + + + + + 快速开发平台(企业版) + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-boot-22-FarstPlus/src/main/resources/templates/views/main.html b/spring-boot-22-FarstPlus/src/main/resources/templates/views/main.html new file mode 100644 index 0000000..f4fb9cc --- /dev/null +++ b/spring-boot-22-FarstPlus/src/main/resources/templates/views/main.html @@ -0,0 +1,24 @@ + + + + + + 欢迎页 + + + + +
      +
      基本信息
      +
      +

      项目介绍

      +
        +
      • 一个轻量级的Java快速开发平台
      • +
      • 友好的代码结构及注释,便于阅读及二次开发
      • +
      • 完善的XSS防范及脚本过滤,彻底杜绝XSS攻击
      • +
      • 实现前后端分离,通过token进行数据交互
      • +
      +
      +
      + + \ No newline at end of file diff --git a/spring-boot-23-MongoDB/pom.xml b/spring-boot-23-MongoDB/pom.xml new file mode 100644 index 0000000..05adac0 --- /dev/null +++ b/spring-boot-23-MongoDB/pom.xml @@ -0,0 +1,30 @@ + + + + spring-boot + cn.timebusker + 2.0.0 + + 4.0.0 + + spring-boot-23-MongoDB + + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + org.springframework.boot + spring-boot-starter-test + + + + org.projectlombok + lombok + provided + + + \ No newline at end of file diff --git a/spring-boot-23-MongoDB/src/main/java/com/timebusker/App.java b/spring-boot-23-MongoDB/src/main/java/com/timebusker/App.java new file mode 100644 index 0000000..32ffc65 --- /dev/null +++ b/spring-boot-23-MongoDB/src/main/java/com/timebusker/App.java @@ -0,0 +1,17 @@ +package com.timebusker; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @DESC:Application + * @author:timebusker + * @date:2018/9/5 + */ +@SpringBootApplication +public class App { + + public static void main(String[] args) { + SpringApplication.run(App.class); + } +} diff --git a/spring-boot-23-MongoDB/src/main/java/com/timebusker/entity/PersonEntity.java b/spring-boot-23-MongoDB/src/main/java/com/timebusker/entity/PersonEntity.java new file mode 100644 index 0000000..4637efa --- /dev/null +++ b/spring-boot-23-MongoDB/src/main/java/com/timebusker/entity/PersonEntity.java @@ -0,0 +1,31 @@ +package com.timebusker.entity; + +import lombok.Data; +import lombok.ToString; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.io.Serializable; + +/** + * @DESC:PersonEntity + * @author:timebusker + * @date:2018/9/6 + */ +@Document(collection = "tb_person") +@Data +@ToString +public class PersonEntity implements Serializable { + + // 指定主键 + @Id + private Integer id; + private String name; + private Integer age; + + public PersonEntity(Integer id, String name, Integer age) { + this.id = id; + this.name = name; + this.age = age; + } +} diff --git a/spring-boot-23-MongoDB/src/main/java/com/timebusker/entity/UserEntity.java b/spring-boot-23-MongoDB/src/main/java/com/timebusker/entity/UserEntity.java new file mode 100644 index 0000000..ddca035 --- /dev/null +++ b/spring-boot-23-MongoDB/src/main/java/com/timebusker/entity/UserEntity.java @@ -0,0 +1,39 @@ +package com.timebusker.entity; + +import lombok.Data; +import lombok.ToString; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.io.Serializable; + +/** + * @DESC:UserEntity + * @author:timebusker + * @date:2018/9/5 + */ + +/** + * 指定MongoDB中集合名称,不指定默认使用类名。 + */ +@Document(collection = "tb_user") +@Data +@ToString +public class UserEntity implements Serializable { + + // 指定主键 + @Id + private Integer id; + private String name; + private Integer age; + + public UserEntity() { + super(); + } + + public UserEntity(Integer id, String name, Integer age) { + this.id = id; + this.name = name; + this.age = age; + } +} diff --git a/spring-boot-23-MongoDB/src/main/java/com/timebusker/repository/AbstractBasicRepository.java b/spring-boot-23-MongoDB/src/main/java/com/timebusker/repository/AbstractBasicRepository.java new file mode 100644 index 0000000..e1f7a19 --- /dev/null +++ b/spring-boot-23-MongoDB/src/main/java/com/timebusker/repository/AbstractBasicRepository.java @@ -0,0 +1,33 @@ +package com.timebusker.repository; + +import java.util.List; +import java.util.Map; + +/** + * @DESC:AbstratCommonRepository + * @author:timebusker + * @date:2018/9/6 + */ +public interface AbstractBasicRepository { + + /** + * 定义参数查询 + * @param params + * @return + */ + T findOneByParams(Map params); + + /** + * 定义参数查询 + * @param params + * @return + */ + List findByParams(Map params); + + /** + * 定义参数分页查询 + * @param params + * @return + */ + List findWithPageByParams(Map params); +} diff --git a/spring-boot-23-MongoDB/src/main/java/com/timebusker/repository/PersonRepository.java b/spring-boot-23-MongoDB/src/main/java/com/timebusker/repository/PersonRepository.java new file mode 100644 index 0000000..f089f31 --- /dev/null +++ b/spring-boot-23-MongoDB/src/main/java/com/timebusker/repository/PersonRepository.java @@ -0,0 +1,13 @@ +package com.timebusker.repository; + +import com.timebusker.entity.PersonEntity; +import org.springframework.data.mongodb.repository.MongoRepository; + +/** + * @DESC:PersonRepository + * @author:timebusker + * @date:2018/9/6 + */ +public interface PersonRepository extends AbstractBasicRepository, MongoRepository { + +} diff --git a/spring-boot-23-MongoDB/src/main/java/com/timebusker/repository/UserRepository.java b/spring-boot-23-MongoDB/src/main/java/com/timebusker/repository/UserRepository.java new file mode 100644 index 0000000..10cb355 --- /dev/null +++ b/spring-boot-23-MongoDB/src/main/java/com/timebusker/repository/UserRepository.java @@ -0,0 +1,26 @@ +package com.timebusker.repository; + +import com.timebusker.entity.UserEntity; +import org.springframework.data.mongodb.repository.MongoRepository; + +/** + * @DESC:UserRepository + * @author:timebusker + * @date:2018/9/5 + */ +public interface UserRepository extends MongoRepository { + + /* + * MongoRepository与HibernateTemplete相似,提供一些基本的方法, + * 实现的方法有findone(),save(),count(),findAll(),findAll(Pageable),delete(),deleteAll()..etc + * 要使用Repository的功能,先继承MongoRepository接口 + * 其中T为仓库保存的bean类,TD为该bean的唯一标识的类型,一般为ObjectId。 + * 之后在spring-boot中注入该接口就可以使用,无需实现里面的方法,spring会根据定义的规则自动生成。 + * starter-data-mongodb 支持方法命名约定查询 findBy{User的name属性名}, + * findBy后面的属性名一定要在User类中存在,否则会报错 + */ + + UserEntity findById(Integer key); + + void deleteById(Integer key); +} diff --git a/spring-boot-23-MongoDB/src/main/java/com/timebusker/repository/impl/PersonRepositoryImpl.java b/spring-boot-23-MongoDB/src/main/java/com/timebusker/repository/impl/PersonRepositoryImpl.java new file mode 100644 index 0000000..2cd7290 --- /dev/null +++ b/spring-boot-23-MongoDB/src/main/java/com/timebusker/repository/impl/PersonRepositoryImpl.java @@ -0,0 +1,67 @@ +package com.timebusker.repository.impl; + +import com.timebusker.entity.PersonEntity; +import com.timebusker.repository.AbstractBasicRepository; +import com.timebusker.repository.PersonRepository; +import com.timebusker.utils.MongoDBPageable; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.stereotype.Repository; + +import java.util.*; + +/** + * @DESC:AbstractBasicRepositoryImpl + * @author:timebusker + * @date:2018/9/6 + */ +@Repository("personRepository") +public class PersonRepositoryImpl implements AbstractBasicRepository { + + @Autowired + private MongoTemplate mongoTemplate; + + @Override + public PersonEntity findOneByParams(Map params) { + Query query = new Query(); + Iterator iterator = params.keySet().iterator(); + while (iterator.hasNext()) { + String key = iterator.next(); + query.addCriteria(Criteria.where(key).is(params.get(key))); + } + PersonEntity personEntity = mongoTemplate.findOne(query, PersonEntity.class); + return personEntity; + } + + @Override + public List findByParams(Map params) { + Query query = new Query(); + Iterator iterator = params.keySet().iterator(); + while (iterator.hasNext()) { + String key = iterator.next(); + query.addCriteria(Criteria.where(key).lt(params.get(key))); + } + List list = mongoTemplate.find(query, PersonEntity.class); + return list; + } + + @Override + public List findWithPageByParams(Map params) { + Query query = new Query(); + MongoDBPageable pageable = new MongoDBPageable(2); + Iterator iterator = params.keySet().iterator(); + while (iterator.hasNext()) { + String key = iterator.next(); + query.addCriteria(Criteria.where(key).lt(params.get(key))); + } + Long allcount = mongoTemplate.count(query, PersonEntity.class); + List list = mongoTemplate.find(query.with(pageable), PersonEntity.class); + Page page = new PageImpl(list, pageable, allcount); + return page.getContent(); + } +} diff --git a/spring-boot-23-MongoDB/src/main/java/com/timebusker/utils/MongoDBPageable.java b/spring-boot-23-MongoDB/src/main/java/com/timebusker/utils/MongoDBPageable.java new file mode 100644 index 0000000..e3e0ec1 --- /dev/null +++ b/spring-boot-23-MongoDB/src/main/java/com/timebusker/utils/MongoDBPageable.java @@ -0,0 +1,96 @@ +package com.timebusker.utils; + +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; + +import java.io.Serializable; + +/** + * @DESC:MongoDBPageable:分页实现类 + * @author:timebusker + * @date:2018/9/7 + */ +public class MongoDBPageable implements Pageable, Serializable { + + private Integer pagenum = 1; + private Integer pagesize = 10; + private Sort sort = null; + + public MongoDBPageable() { + } + + public MongoDBPageable(Integer pagenum) { + this.pagenum = pagenum; + } + + public MongoDBPageable(Integer pagenum, Integer pagesize) { + this.pagenum = pagenum; + this.pagesize = pagesize; + } + + public MongoDBPageable(Integer pagenum, Integer pagesize, Sort sort) { + this.pagenum = pagenum; + this.pagesize = pagesize; + this.sort = sort; + } + + @Override + public int getPageNumber() { + return 0; + } + + @Override + public int getPageSize() { + return getPagesize(); + } + + @Override + public int getOffset() { + return (getPagenum() - 1) * getPageSize(); + } + + @Override + public Sort getSort() { + return sort; + } + + @Override + public Pageable next() { + return null; + } + + @Override + public Pageable previousOrFirst() { + return null; + } + + @Override + public Pageable first() { + return null; + } + + @Override + public boolean hasPrevious() { + return false; + } + + public Integer getPagenum() { + return pagenum; + } + + public void setPagenum(Integer pagenum) { + this.pagenum = pagenum; + } + + public Integer getPagesize() { + return pagesize; + } + + public void setPagesize(Integer pagesize) { + this.pagesize = pagesize; + } + + public void setSort(Sort sort) { + this.sort = sort; + } +} diff --git a/spring-boot-23-MongoDB/src/main/resources/application.properties b/spring-boot-23-MongoDB/src/main/resources/application.properties new file mode 100644 index 0000000..afc474d --- /dev/null +++ b/spring-boot-23-MongoDB/src/main/resources/application.properties @@ -0,0 +1,2 @@ +# \u6570\u636E\u5E93\u4E0D\u5B58\u5728\u4F1A\u81EA\u52A8\u521B\u5EFA +spring.data.mongodb.uri=mongodb://12.12.12.23:27017/test \ No newline at end of file diff --git a/spring-boot-23-MongoDB/src/test/java/com/timebusker/PersonDbOpsTest.java b/spring-boot-23-MongoDB/src/test/java/com/timebusker/PersonDbOpsTest.java new file mode 100644 index 0000000..193cae8 --- /dev/null +++ b/spring-boot-23-MongoDB/src/test/java/com/timebusker/PersonDbOpsTest.java @@ -0,0 +1,86 @@ +package com.timebusker; + +import com.timebusker.entity.PersonEntity; +import com.timebusker.repository.PersonRepository; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.*; + +/** + * @DESC:PersonDbOpsTest + * @author:timebusker + * @date:2018/9/6 + */ +@RunWith(SpringRunner.class) +@SpringBootTest +public class PersonDbOpsTest { + + @Autowired + private PersonRepository repository; + + /** + * SAVE:主键重复则为更新操作,不重复则为插入新增操作 + * insert:只进行插入操作,若主键重复则抛异常 + */ + @Test + public void InsertDb() { + for (int i = 0; i < 50; i++) { + PersonEntity person = new PersonEntity(i, "timebuser__" + i, i * 10); + repository.save(person); + System.err.println(person.toString()); + } + } + + @Test + public void updateDb() { + for (int i = 0; i < 20; i++) { + PersonEntity person = new PersonEntity(i, "AAAAAAAAAA__" + i, i * 10); + repository.save(person); + System.err.println(person.toString()); + } + } + + @Test + public void deleteDB() { + repository.delete(1); + Map params = new HashMap<>(); + params.put("id", 1); + PersonEntity person = (PersonEntity) repository.findOneByParams(params); + System.err.println(person); + } + + @Test + public void findOneByParams() { + Map params = new HashMap<>(); + params.put("id", 1); + PersonEntity person = (PersonEntity) repository.findOneByParams(params); + System.err.println(person); + } + + @Test + public void findByParams() { + Map params = new HashMap<>(); + params.put("id", 40); + List list = repository.findByParams(params); + for (PersonEntity person : list) { + System.err.println(person.toString()); + } + } + + /** + * 指定查询第2页数据 + */ + @Test + public void findWithPageByParams() { + Map params = new HashMap<>(); + params.put("id", 40); + List list = repository.findWithPageByParams(params); + for (PersonEntity person : list) { + System.err.println(person.toString()); + } + } +} diff --git a/spring-boot-23-MongoDB/src/test/java/com/timebusker/UserDbOpsTest.java b/spring-boot-23-MongoDB/src/test/java/com/timebusker/UserDbOpsTest.java new file mode 100644 index 0000000..4bb1c8c --- /dev/null +++ b/spring-boot-23-MongoDB/src/test/java/com/timebusker/UserDbOpsTest.java @@ -0,0 +1,48 @@ +package com.timebusker; + +import com.timebusker.entity.UserEntity; +import com.timebusker.repository.UserRepository; +import net.minidev.json.reader.JsonWriterI; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * @DESC:UserDbOpsTest + * @author:timebusker + * @date:2018/9/5 + */ +@RunWith(SpringRunner.class) +@SpringBootTest +public class UserDbOpsTest { + + @Autowired + private UserRepository dao; + + @Test + public void testInsert() { + UserEntity u = new UserEntity(1, "timebusker", 21); + dao.save(u); + } + + @Test + public void testQuery() { + System.out.println("****************************\n\n"); + System.out.println(dao.findById(1)); + System.out.println("\n\n****************************"); + } + + @Test + public void testUpdate(){ + UserEntity u = new UserEntity(1, "timebusker", 21); + dao.save(u); + } + + @Test + public void testDelete(){ + UserEntity u = new UserEntity(1, "timebusker", 21); + dao.deleteById(1); + } +} diff --git a/spring-boot-24-WebSocket/pom.xml b/spring-boot-24-WebSocket/pom.xml new file mode 100644 index 0000000..cb34b68 --- /dev/null +++ b/spring-boot-24-WebSocket/pom.xml @@ -0,0 +1,25 @@ + + + + spring-boot + cn.timebusker + 2.0.0 + + 4.0.0 + + spring-boot-24-WebSocket + + + + org.springframework.boot + spring-boot-starter-websocket + + + org.springframework.boot + spring-boot-starter-test + test + + + diff --git a/spring-boot-24-WebSocket/src/main/java/com/timebusker/App.java b/spring-boot-24-WebSocket/src/main/java/com/timebusker/App.java new file mode 100644 index 0000000..8576c03 --- /dev/null +++ b/spring-boot-24-WebSocket/src/main/java/com/timebusker/App.java @@ -0,0 +1,9 @@ +package com.timebusker; + +/** + * @DESC:Application + * @author:timebusker + * @date:2018/10/30 + */ +public class App { +} diff --git a/spring-boot-24-WebSocket/src/main/java/com/timebusker/conf/WebSocketConfig.java b/spring-boot-24-WebSocket/src/main/java/com/timebusker/conf/WebSocketConfig.java new file mode 100644 index 0000000..74ddf68 --- /dev/null +++ b/spring-boot-24-WebSocket/src/main/java/com/timebusker/conf/WebSocketConfig.java @@ -0,0 +1,20 @@ +package com.timebusker.conf; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +/** + * @DESC:WebSocketConfig + * @author:timebusker + * @date:2018/10/30 + */ + +@Configuration +public class WebSocketConfig { + + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/spring-boot-3-logs/.gitignore b/spring-boot-3-logs/.gitignore index 28972e5..bec3fb0 100644 --- a/spring-boot-3-logs/.gitignore +++ b/spring-boot-3-logs/.gitignore @@ -1,4 +1,5 @@ .settings/ target/ .classpath -.project \ No newline at end of file +.project +*.iml \ No newline at end of file diff --git a/spring-boot-3-logs/spring-boot-3-logs-Log4j/pom.xml b/spring-boot-3-logs/spring-boot-3-logs-Log4j/pom.xml index 0595a94..7409efa 100644 --- a/spring-boot-3-logs/spring-boot-3-logs-Log4j/pom.xml +++ b/spring-boot-3-logs/spring-boot-3-logs-Log4j/pom.xml @@ -93,10 +93,10 @@ 512m true - 1.3 + 1.8 UTF-8 - -verbose -bootclasspath ${java.home}\lib\rt.jar + diff --git a/spring-boot-3-logs/spring-boot-3-logs-Log4j/spring-boot-3-logs-Log4j.iml b/spring-boot-3-logs/spring-boot-3-logs-Log4j/spring-boot-3-logs-Log4j.iml deleted file mode 100644 index a5d3b69..0000000 --- a/spring-boot-3-logs/spring-boot-3-logs-Log4j/spring-boot-3-logs-Log4j.iml +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-3-logs/spring-boot-3-logs-Log4j2/spring-boot-3-logs-Log4j2.iml b/spring-boot-3-logs/spring-boot-3-logs-Log4j2/spring-boot-3-logs-Log4j2.iml deleted file mode 100644 index 528ac7e..0000000 --- a/spring-boot-3-logs/spring-boot-3-logs-Log4j2/spring-boot-3-logs-Log4j2.iml +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-3-logs/spring-boot-3-logs-Logback/README.md b/spring-boot-3-logs/spring-boot-3-logs-Logback/README.md index 77bbf6d..5392484 100644 --- a/spring-boot-3-logs/spring-boot-3-logs-Logback/README.md +++ b/spring-boot-3-logs/spring-boot-3-logs-Logback/README.md @@ -74,4 +74,34 @@ ``` ----- \ No newline at end of file +---- + +```$xslt + + + + + + + %date [%thread] %-5level %logger{80} || %msg%n + + + + /logs/timebusker.log + + /logs/timebusker-%d{yyyy-MM-dd}.log + 30 + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n + + false + false + + + + + + + +``` \ No newline at end of file diff --git a/spring-boot-3-logs/spring-boot-3-logs-Logback/spring-boot-3-logs-Logback.iml b/spring-boot-3-logs/spring-boot-3-logs-Logback/spring-boot-3-logs-Logback.iml deleted file mode 100644 index 2db83f7..0000000 --- a/spring-boot-3-logs/spring-boot-3-logs-Logback/spring-boot-3-logs-Logback.iml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-3-logs/spring-boot-3-logs.iml b/spring-boot-3-logs/spring-boot-3-logs.iml deleted file mode 100644 index a0d4a1e..0000000 --- a/spring-boot-3-logs/spring-boot-3-logs.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-4-Scheduled/.gitignore b/spring-boot-4-Scheduled/.gitignore index 28972e5..bec3fb0 100644 --- a/spring-boot-4-Scheduled/.gitignore +++ b/spring-boot-4-Scheduled/.gitignore @@ -1,4 +1,5 @@ .settings/ target/ .classpath -.project \ No newline at end of file +.project +*.iml \ No newline at end of file diff --git a/spring-boot-4-Scheduled/spring-boot-4-Scheduled.iml b/spring-boot-4-Scheduled/spring-boot-4-Scheduled.iml deleted file mode 100644 index dafbb7f..0000000 --- a/spring-boot-4-Scheduled/spring-boot-4-Scheduled.iml +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-5-Async/.gitignore b/spring-boot-5-Async/.gitignore index 28972e5..bec3fb0 100644 --- a/spring-boot-5-Async/.gitignore +++ b/spring-boot-5-Async/.gitignore @@ -1,4 +1,5 @@ .settings/ target/ .classpath -.project \ No newline at end of file +.project +*.iml \ No newline at end of file diff --git a/spring-boot-5-Async/pom.xml b/spring-boot-5-Async/pom.xml index 62b044b..20a5d2e 100644 --- a/spring-boot-5-Async/pom.xml +++ b/spring-boot-5-Async/pom.xml @@ -89,7 +89,5 @@ logback-core - - diff --git a/spring-boot-5-Async/spring-boot-5-Async.iml b/spring-boot-5-Async/spring-boot-5-Async.iml deleted file mode 100644 index 2db83f7..0000000 --- a/spring-boot-5-Async/spring-boot-5-Async.iml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-6-GlobalException/.gitignore b/spring-boot-6-GlobalException/.gitignore index 28972e5..bec3fb0 100644 --- a/spring-boot-6-GlobalException/.gitignore +++ b/spring-boot-6-GlobalException/.gitignore @@ -1,4 +1,5 @@ .settings/ target/ .classpath -.project \ No newline at end of file +.project +*.iml \ No newline at end of file diff --git a/spring-boot-6-GlobalException/spring-boot-6-GlobalException.iml b/spring-boot-6-GlobalException/spring-boot-6-GlobalException.iml deleted file mode 100644 index f7f7a1b..0000000 --- a/spring-boot-6-GlobalException/spring-boot-6-GlobalException.iml +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-6-GlobalException/src/main/java/cn/timebusker/App.java b/spring-boot-6-GlobalException/src/main/java/cn/timebusker/App.java index 8b1f6c1..e40b98d 100644 --- a/spring-boot-6-GlobalException/src/main/java/cn/timebusker/App.java +++ b/spring-boot-6-GlobalException/src/main/java/cn/timebusker/App.java @@ -9,40 +9,35 @@ @SpringBootApplication public class App { - /** - * @SpringBootApplication注解的类一定要放在自定义包下且属于自定义包的 - * - * @SpringBootApplication is a convenience annotation that adds all of the following: - * @SpringBootApplication是一个方便的注解,增加了所有的以下内容: - * - * @Configuration tags the class as a source of bean definitions for the application context. - * @Configuration 标记一个类来作为bean定义的应用程序上下文的资源 - * - * @EnableAutoConfiguration tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings. - * @EnableAutoConfiguration告诉Spring Boot开始加载基于类路径下的配置信息、beans、各种属性配置。 - * - * Normally you would add @EnableWebMvc for a Spring MVC app, but Spring Boot adds - * it automatically when it sees spring-webmvc on the classpath. This flags the application as a web - * application and activates key behaviors such as setting up a DispatcherServlet - * 通常你会添加@EnableWebMvc为Spring MVC的应用程序,但是当Spring Boot在classpath下检索到spring-webmvc时, - * spring boot会自动添加。这标志该应用程序作为Web应用程序,并激活关键行为,如设立的DispatcherServlet - * - * @ComponentScan tells Spring to look for other components, configurations, and services in the the hello package, allowing it to find the HelloController. - * @ComponentScan 告诉Spring寻找其他组件,配置,以及业务层类,最前面才能加载到所有的类。 - */ - - public static void main(String[] args) { - // devtools:是spring boot的一个热部署工具 - //设置 spring.devtools.restart.enabled 属性为false,可以关闭该特性. - //System.setProperty("spring.devtools.restart.enabled","false"); - - // 启动Sprign Boot - ApplicationContext ctx = SpringApplication.run(App.class, args); - System.out.println("Let's inspect the beans provided by Spring Boot:"); - String[] beanNames = ctx.getBeanDefinitionNames(); - Arrays.sort(beanNames); - for (String beanName : beanNames) { - System.out.println(beanName); - } - } + /** + * @SpringBootApplication注解的类一定要放在自定义包下且属于自定义包的 + * @SpringBootApplication is a convenience annotation that adds all of the following: + * @SpringBootApplication是一个方便的注解,增加了所有的以下内容: + * @Configuration tags the class as a source of bean definitions for the application context. + * @Configuration 标记一个类来作为bean定义的应用程序上下文的资源 + * @EnableAutoConfiguration tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings. + * @EnableAutoConfiguration告诉Spring Boot开始加载基于类路径下的配置信息、beans、各种属性配置。 + *

      + * Normally you would add @EnableWebMvc for a Spring MVC app, but Spring Boot adds + * it automatically when it sees spring-webmvc on the classpath. This flags the application as a web + * application and activates key behaviors such as setting up a DispatcherServlet + * 通常你会添加@EnableWebMvc为Spring MVC的应用程序,但是当Spring Boot在classpath下检索到spring-webmvc时, + * spring boot会自动添加。这标志该应用程序作为Web应用程序,并激活关键行为,如设立的DispatcherServlet + * @ComponentScan tells Spring to look for other components, configurations, and services in the the hello package, allowing it to find the HelloController. + * @ComponentScan 告诉Spring寻找其他组件,配置,以及业务层类,最前面才能加载到所有的类。 + */ + + public static void main(String[] args) { + // devtools:是spring boot的一个热部署工具 + //设置 spring.devtools.restart.enabled 属性为false,可以关闭该特性. + //System.setProperty("spring.devtools.restart.enabled","false"); + // 启动Sprign Boot + ApplicationContext ctx = SpringApplication.run(App.class, args); + System.out.println("Let's inspect the beans provided by Spring Boot:"); +// String[] beanNames = ctx.getBeanDefinitionNames(); +// Arrays.sort(beanNames); +// for (String beanName : beanNames) { +// System.out.println(beanName); +// } + } } diff --git a/spring-boot-6-GlobalException/src/main/java/cn/timebusker/web/GlobalExceptionController.java b/spring-boot-6-GlobalException/src/main/java/cn/timebusker/web/GlobalExceptionController.java index 5f0d763..417c0b1 100644 --- a/spring-boot-6-GlobalException/src/main/java/cn/timebusker/web/GlobalExceptionController.java +++ b/spring-boot-6-GlobalException/src/main/java/cn/timebusker/web/GlobalExceptionController.java @@ -12,56 +12,56 @@ /** * 创建全局异常处理类:通过使用@ControllerAdvice定义统一的异常处理类,而不是在每个Controller中逐个定义。 - * + * * @ControllerAdvice统一定义不同Exception映射到不同错误处理页面 */ @ControllerAdvice public class GlobalExceptionController { - /** - * 在@ControllerAdvice类中,根据抛出的具体Exception类型匹配@ExceptionHandler中配置的异常类型来匹配错误映射和处理 - */ + /** + * 在@ControllerAdvice类中,根据抛出的具体Exception类型匹配@ExceptionHandler中配置的异常类型来匹配错误映射和处理 + */ - public static final String DEFAULT_ERROR_VIEW = "error"; + public static final String DEFAULT_ERROR_VIEW = "error"; - /** - * 捕获自定义异常,返回json信息 - */ - @ExceptionHandler(value = MineException.class) - @ResponseBody - public ErrorMassage ErrorHandler(HttpServletRequest req, MineException e) throws Exception { - ErrorMassage error = new ErrorMassage<>(); - error.setCode(404); - error.setMessage("Not Found Exception !!!"); - error.setUrl(req.getRequestURL().toString()); - error.setData(e); - return error; - } - - @ExceptionHandler(value = ArithmeticException.class) - @ResponseBody - public ErrorMassage ErrorHandler(HttpServletRequest req, ArithmeticException e) throws Exception { - ErrorMassage error = new ErrorMassage<>(); - error.setCode(405); - error.setMessage("java.lang.ArithmeticException: / by zero"); - error.setUrl(req.getRequestURL().toString()); - error.setData(e); - return error; - } - - /** - * @ExceptionHandler用来定义函数针对的异常类型,最后将Exception对象和请求URL映射到error.html中 - */ - @ExceptionHandler(value = Exception.class) - public ModelAndView ErrorHandler(HttpServletRequest req, Exception e) throws Exception { - ModelAndView mav = new ModelAndView(); - ErrorMassage error = new ErrorMassage(); - error.setCode(400); - error.setMessage("系统异常"); - error.setUrl(req.getRequestURI()); - error.setData(e); - mav.addObject(error); - mav.setViewName(DEFAULT_ERROR_VIEW); - return mav; - } + /** + * 捕获自定义异常,返回json信息 + */ + @ExceptionHandler(value = MineException.class) + @ResponseBody + public ErrorMassage ErrorHandler(HttpServletRequest req, MineException e) throws Exception { + ErrorMassage error = new ErrorMassage<>(); + error.setCode(404); + error.setMessage("Not Found Exception......"); + error.setUrl(req.getRequestURL().toString()); + error.setData(""); + return error; + } + + @ExceptionHandler(value = ArithmeticException.class) + @ResponseBody + public ErrorMassage ErrorHandler(HttpServletRequest req, ArithmeticException e) throws Exception { + ErrorMassage error = new ErrorMassage<>(); + error.setCode(405); + error.setMessage("java.lang.ArithmeticException: / by zero"); + error.setUrl(req.getRequestURL().toString()); + error.setData(e); + return error; + } + + /** + * @ExceptionHandler用来定义函数针对的异常类型,最后将Exception对象和请求URL映射到error.html中 + */ + @ExceptionHandler(value = Exception.class) + public ModelAndView ErrorHandler(HttpServletRequest req, Exception e) throws Exception { + ModelAndView mav = new ModelAndView(); + ErrorMassage error = new ErrorMassage(); + error.setCode(400); + error.setMessage("系统异常"); + error.setUrl(req.getRequestURI()); + error.setData(e); + mav.addObject(error); + mav.setViewName(DEFAULT_ERROR_VIEW); + return mav; + } } diff --git a/spring-boot-6-GlobalException/src/main/java/cn/timebusker/web/IndexController.java b/spring-boot-6-GlobalException/src/main/java/cn/timebusker/web/IndexController.java index 3c8ff6c..65f057a 100644 --- a/spring-boot-6-GlobalException/src/main/java/cn/timebusker/web/IndexController.java +++ b/spring-boot-6-GlobalException/src/main/java/cn/timebusker/web/IndexController.java @@ -28,8 +28,8 @@ public String anyone(ModelMap map) throws Exception { } @RequestMapping("/mine") - public String mine(ModelMap map) throws MineException { - logger.info("访问到了 mine ..."); + public String mine(ModelMap map) { + logger.info("访问到了\t\tmine ..."); Throwable throwable = new Throwable(); throw new MineException("我们访问到了 mine ...", throwable); } diff --git a/spring-boot-6-GlobalException/src/main/resources/templates/error.html b/spring-boot-6-GlobalException/src/main/resources/templates/error.html index 6742c60..343c1af 100644 --- a/spring-boot-6-GlobalException/src/main/resources/templates/error.html +++ b/spring-boot-6-GlobalException/src/main/resources/templates/error.html @@ -1,5 +1,5 @@ - + 统一异常处理 diff --git a/spring-boot-6-GlobalException/src/main/resources/templates/index.html b/spring-boot-6-GlobalException/src/main/resources/templates/index.html index 30b1ec2..87945c2 100644 --- a/spring-boot-6-GlobalException/src/main/resources/templates/index.html +++ b/spring-boot-6-GlobalException/src/main/resources/templates/index.html @@ -1,5 +1,5 @@ - + Insert title here diff --git a/spring-boot-7-EhCache/.gitignore b/spring-boot-7-EhCache/.gitignore index 28972e5..bec3fb0 100644 --- a/spring-boot-7-EhCache/.gitignore +++ b/spring-boot-7-EhCache/.gitignore @@ -1,4 +1,5 @@ .settings/ target/ .classpath -.project \ No newline at end of file +.project +*.iml \ No newline at end of file diff --git a/spring-boot-7-EhCache/spring-boot-7-EhCache.iml b/spring-boot-7-EhCache/spring-boot-7-EhCache.iml deleted file mode 100644 index a0e9060..0000000 --- a/spring-boot-7-EhCache/spring-boot-7-EhCache.iml +++ /dev/null @@ -1,115 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-7-EhCache/src/main/java/cn/timebusker/service/Impl/UserServiceImpl.java b/spring-boot-7-EhCache/src/main/java/cn/timebusker/service/Impl/UserServiceImpl.java index d14a537..1ffa5bb 100644 --- a/spring-boot-7-EhCache/src/main/java/cn/timebusker/service/Impl/UserServiceImpl.java +++ b/spring-boot-7-EhCache/src/main/java/cn/timebusker/service/Impl/UserServiceImpl.java @@ -1,71 +1,71 @@ -package cn.timebusker.service.Impl; - -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cache.annotation.CacheConfig; -import org.springframework.cache.annotation.CacheEvict; -import org.springframework.cache.annotation.CachePut; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.stereotype.Service; - -import cn.timebusker.dao.UserRepository; -import cn.timebusker.entity.User; -import cn.timebusker.service.UserService; - -@Service -@CacheConfig(cacheNames = "user-cache") -public class UserServiceImpl implements UserService { - - public static final String CACHE_KEY = "USERS_CACHE_KEY"; - - @Autowired - UserRepository repository; - - /** - * 使用ID查询用户 - * - * @param id - * @return - */ - @Override - @Cacheable(value = {}) - public User findUserById(long id) { - User u = repository.findOne(id); - return u; - } - - /** - * 查询所有用户 - * - * @return - */ - @Override - @Cacheable - public List findAllUser() { - List list = repository.findAll(); - return list; - } - - /** - * 更新或者新增用户信息 - * - * @param user - */ - @Override - @CachePut - public void saveAndFlush(User user) { - repository.saveAndFlush(user); - } - - /** - * 通过ID删除一个用户 - * - * @param id - */ - @Override - @CacheEvict - public void deleteUserById(long id) { - repository.delete(id); - } -} +//package cn.timebusker.service.Impl; +// +//import java.util.List; +// +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.cache.annotation.CacheConfig; +//import org.springframework.cache.annotation.CacheEvict; +//import org.springframework.cache.annotation.CachePut; +//import org.springframework.cache.annotation.Cacheable; +//import org.springframework.stereotype.Service; +// +//import cn.timebusker.dao.UserRepository; +//import cn.timebusker.entity.User; +//import cn.timebusker.service.UserService; +// +//@Service +//@CacheConfig(cacheNames = "user-cache") +//public class UserServiceImpl implements UserService { +// +// public static final String CACHE_KEY = "USERS_CACHE_KEY"; +// +// @Autowired +// UserRepository repository; +// +// /** +// * 使用ID查询用户 +// * +// * @param id +// * @return +// */ +// @Override +// @Cacheable(value = {"#id"}) +// public User findUserById(long id) { +// User u = null;//repository.findOne(id); +// return u; +// } +// +// /** +// * 查询所有用户 +// * +// * @return +// */ +// @Override +// @Cacheable +// public List findAllUser() { +// List list = repository.findAll(); +// return list; +// } +// +// /** +// * 更新或者新增用户信息 +// * +// * @param user +// */ +// @Override +// @CachePut +// public void saveAndFlush(User user) { +// repository.saveAndFlush(user); +// } +// +// /** +// * 通过ID删除一个用户 +// * +// * @param id +// */ +// @Override +// @CacheEvict +// public void deleteUserById(Long id) { +// repository.delete(id); +// } +//} diff --git a/spring-boot-7-EhCache/src/main/java/cn/timebusker/service/UserService.java b/spring-boot-7-EhCache/src/main/java/cn/timebusker/service/UserService.java index 9dbee49..cfe0e18 100644 --- a/spring-boot-7-EhCache/src/main/java/cn/timebusker/service/UserService.java +++ b/spring-boot-7-EhCache/src/main/java/cn/timebusker/service/UserService.java @@ -12,7 +12,7 @@ public interface UserService { * @param id * @return */ - public User findUserById(long id); + public User findUserById(Long id); /** * 查询所有用户 @@ -34,5 +34,5 @@ public interface UserService { * * @param id */ - public void deleteUserById(long id); + public void deleteUserById(Long id); } diff --git a/spring-boot-8-AOP/.gitignore b/spring-boot-8-AOP/.gitignore index 28972e5..bec3fb0 100644 --- a/spring-boot-8-AOP/.gitignore +++ b/spring-boot-8-AOP/.gitignore @@ -1,4 +1,5 @@ .settings/ target/ .classpath -.project \ No newline at end of file +.project +*.iml \ No newline at end of file diff --git a/spring-boot-8-AOP/spring-boot-8-AOP.iml b/spring-boot-8-AOP/spring-boot-8-AOP.iml deleted file mode 100644 index cd78539..0000000 --- a/spring-boot-8-AOP/spring-boot-8-AOP.iml +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-8-AOP/src/main/java/cn/timebusker/aop/LoggerHandlerAop.java b/spring-boot-8-AOP/src/main/java/cn/timebusker/aop/LoggerHandlerAop.java index 3a0d8ce..abfe983 100644 --- a/spring-boot-8-AOP/src/main/java/cn/timebusker/aop/LoggerHandlerAop.java +++ b/spring-boot-8-AOP/src/main/java/cn/timebusker/aop/LoggerHandlerAop.java @@ -28,193 +28,197 @@ @Order(1) public class LoggerHandlerAop { - private final static Logger logger = LoggerFactory.getLogger(LoggerHandlerAop.class); + private final static Logger logger = LoggerFactory.getLogger(LoggerHandlerAop.class); - /** - * AOP切面中的同步问题:用于监控业务处理性能 - */ - ThreadLocal startTime = new ThreadLocal<>(); + /** + * AOP切面中的同步问题:用于监控业务处理性能 + */ + ThreadLocal startTime = new ThreadLocal<>(); // ==========================================================匹配切点表达式======================================================================================== + + /** + * 一、execution(方法表达式) + * 1、匹配方法时,只能匹配到实现类,匹配到接口类不能成功 + * 2、匹配方法执行 + */ + // 匹配cn.timebusker.service包及子包下的任何方法执行 + @Pointcut(value = "execution(* cn.timebusker.service.*.*(..))") + public void log1() { + } + + // 匹配任何包下的service包及子包下的任何方法执行(该模式只能匹配到一级的子包,多级子包不适用) + @Pointcut(value = "execution(* *..service.*.*(..))") + public void log2() { + } + + // 匹配任何包下的service包及子包下的任何方法执行(该模式能匹配到任何多级的子包下的方法执行) + @Pointcut(value = "execution(* *..service..*(..))") + public void log3() { + } + + // 匹配返回值类型为java.lang.String的任何包下的service包及子包下的方法执行 + @Pointcut(value = "execution(java.lang.String *..service..*(..))") + public void log4() { + } + + // 匹配返回值类型为int的任何包下的service包及子包下的方法执行 + @Pointcut(value = "execution(int *..service..*(..))") + public void log5() { + } + + // 匹配任何返回值类型的cn.timebusker包及任何子包下的以add开头的参数为Strign类型的方法执行 + @Pointcut(value = "execution(* cn.timebusker..add*(String))") + public void log6() { + } + + // 匹配 OR、AND + @Pointcut(value = "execution(* cn.timebusker.service.*.add*(int))") + public void log7() { + } + + // 匹配 OR、AND、 + @Pointcut(value = "execution(* cn.timebusker.service.*.add*(int)) OR execution(* cn.timebusker..add*(String))") + public void log8() { + } + + /** + * 二、within(类型表达式) + * 1、匹配类型时,只能匹配到实现类,匹配到接口类不能成功 + * 2、匹配指定类型内的方法执行; + */ + // 匹配指定类型内的方法执行--只能匹配类型 + @Pointcut(value = "within(cn.timebusker.service.order.Impl.OrderInfoServiceImpl)") + public void logw1() { + } + + // 匹配指定类型内的方法执行(包下所有的类) + @Pointcut(value = "within(cn.timebusker.service.order.Impl.*)") + public void logw2() { + } + + /** + * 三、this(类型全限定名) + * 1、可以直接匹配接口类型完成 类型全名限定匹配 + * 2、注意是AOP代理对象的类型匹配,这样就可能包括引入接口方法也可以匹配;注意this中使用的表达式必须是类型全限定名,不支持通配符 + */ + // 匹配指定类型内的方法执行(包下所有的类) + @Pointcut(value = "this(cn.timebusker.service.order.OrderInfoService)") + public void logt1() { + } + + /** + * 四、target(类型全限定名)--匹配当前目标对象类型的执行方法 + * 1、可以直接匹配接口类型完成 类型全名限定匹配 + * 2、注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配;注意target中使用的表达式必须是类型全限定名,不支持通配符 + */ + // 匹配指定类型内的方法执行(包下所有的类) + @Pointcut(value = "target(cn.timebusker.service.order.OrderInfoService)") + public void logt2() { + } + /** - * 一、execution(方法表达式) - * 1、匹配方法时,只能匹配到实现类,匹配到接口类不能成功 - * 2、匹配方法执行 - */ - // 匹配cn.timebusker.service包及子包下的任何方法执行 - @Pointcut(value="execution(* cn.timebusker.service.*.*(..))") - public void log1() { - } - - // 匹配任何包下的service包及子包下的任何方法执行(该模式只能匹配到一级的子包,多级子包不适用) - @Pointcut(value="execution(* *..service.*.*(..))") - public void log2() { - } - - // 匹配任何包下的service包及子包下的任何方法执行(该模式能匹配到任何多级的子包下的方法执行) - @Pointcut(value = "execution(* *..service..*(..))") - public void log3() { - } - - // 匹配返回值类型为java.lang.String的任何包下的service包及子包下的方法执行 - @Pointcut(value = "execution(java.lang.String *..service..*(..))") - public void log4() { - } - - // 匹配返回值类型为int的任何包下的service包及子包下的方法执行 - @Pointcut(value = "execution(int *..service..*(..))") - public void log5() { - } - - // 匹配任何返回值类型的cn.timebusker包及任何子包下的以add开头的参数为Strign类型的方法执行 - @Pointcut(value = "execution(* cn.timebusker..add*(String))") - public void log6() { - } - - // 匹配 OR、AND - @Pointcut(value = "execution(* cn.timebusker.service.*.add*(int))") - public void log7() { - } - - // 匹配 OR、AND、 - @Pointcut(value = "execution(* cn.timebusker.service.*.add*(int)) OR execution(* cn.timebusker..add*(String))") - public void log8() { - } - -/** - * 二、within(类型表达式) - * 1、匹配类型时,只能匹配到实现类,匹配到接口类不能成功 - * 2、匹配指定类型内的方法执行; + * 五、args(参数类型列表)--匹配当前执行的方法传入的参数为指定类型的执行方法 + * 1、注意是匹配传入的参数类型,不是匹配方法签名的参数类型;参数类型列表中的参数必须是类型全限定名,通配符不支持; + * 2、args属于动态切入点,是在运行时动态匹配的,这种切入点开销非常大,非特殊情况最好不要使用; + * 3、此处不作示例 */ - // 匹配指定类型内的方法执行--只能匹配类型 - @Pointcut(value = "within(cn.timebusker.service.order.Impl.OrderInfoServiceImpl)") - public void logw1() { - } - - // 匹配指定类型内的方法执行(包下所有的类) - @Pointcut(value = "within(cn.timebusker.service.order.Impl.*)") - public void logw2() { - } + + /** + * 六、@within(注解类型)--匹配所以持有指定注解类型内的方法;注解类型也必须是全限定类型名; + * 1、注解类型也必须是全限定类型名; + */ + // 匹配被org.springframework.stereotype.Service这个注解标注的类----注解标注在接口上不起作用 + @Pointcut(value = "@within(org.springframework.stereotype.Service)") + public void logaw1() { + } + + // 匹配 自定义注解标注的类----注解标注在接口上不起作用 + @Pointcut(value = "@within(cn.timebusker.annotation.timebuskerBean)") + public void logaw2() { + } /** - * 三、this(类型全限定名) - * 1、可以直接匹配接口类型完成 类型全名限定匹配 - * 2、注意是AOP代理对象的类型匹配,这样就可能包括引入接口方法也可以匹配;注意this中使用的表达式必须是类型全限定名,不支持通配符 + * 七、@target(注解类型)--匹配当前目标对象类型的执行方法 + * 1、目标对象持有指定的注解; + * 2、注解类型也必须是全限定类型名; + * 3、此处不作示例 */ - // 匹配指定类型内的方法执行(包下所有的类) - @Pointcut(value = "this(cn.timebusker.service.order.OrderInfoService)") - public void logt1() { - } - -/** -* 四、target(类型全限定名)--匹配当前目标对象类型的执行方法 -* 1、可以直接匹配接口类型完成 类型全名限定匹配 -* 2、注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配;注意target中使用的表达式必须是类型全限定名,不支持通配符 -*/ - // 匹配指定类型内的方法执行(包下所有的类) - @Pointcut(value = "target(cn.timebusker.service.order.OrderInfoService)") - public void logt2() { - } - -/** -* 五、args(参数类型列表)--匹配当前执行的方法传入的参数为指定类型的执行方法 -* 1、注意是匹配传入的参数类型,不是匹配方法签名的参数类型;参数类型列表中的参数必须是类型全限定名,通配符不支持; -* 2、args属于动态切入点,是在运行时动态匹配的,这种切入点开销非常大,非特殊情况最好不要使用; -* 3、此处不作示例 -*/ - -/** -* 六、@within(注解类型)--匹配所以持有指定注解类型内的方法;注解类型也必须是全限定类型名; -* 1、注解类型也必须是全限定类型名; -*/ - // 匹配被org.springframework.stereotype.Service这个注解标注的类----注解标注在接口上不起作用 - @Pointcut(value = "@within(org.springframework.stereotype.Service)") - public void logaw1() { - } - - // 匹配 自定义注解标注的类----注解标注在接口上不起作用 - @Pointcut(value = "@within(cn.timebusker.annotation.timebuskerBean)") - public void logaw2() { - } - -/** -* 七、@target(注解类型)--匹配当前目标对象类型的执行方法 -* 1、目标对象持有指定的注解; -* 2、注解类型也必须是全限定类型名; -* 3、此处不作示例 -*/ -/** -* 八、@annotation(注解类型)--匹配当前执行方法持有指定注解的方法 -* 1、注解类型也必须是全限定类型名; -*/ - // 匹配 自定义注解标注的类----注解标注在接口的方法上不起作用 - @Pointcut(value = "@annotation(cn.timebusker.annotation.timebuskerMethod)") - public void logaa1() { - } + /** + * 八、@annotation(注解类型)--匹配当前执行方法持有指定注解的方法 + * 1、注解类型也必须是全限定类型名; + */ + // 匹配 自定义注解标注的类----注解标注在接口的方法上不起作用 + @Pointcut(value = "@annotation(cn.timebusker.annotation.timebuskerMethod)") + public void logaa1() { + } // ==========================================================匹配切点表达式======================================================================================== - /** - * 前置通知:在连接点执行前的通知,但不能阻止连接点前的执行(除非它抛出一个异常) - */ + /** + * 前置通知:在连接点执行前的通知,但不能阻止连接点前的执行(除非它抛出一个异常) + */ // 引用多个切入点 // @Before("log6() OR log7()") // 引用单个切入点 - @Before("logaa1()") - public void beforeAdvice(JoinPoint point) { - logger.info("SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS"); - logger.info("LoggerHandlerAop.beforeAdvice...time:" + DateUtil.now()); - Signature signature = point.getSignature(); - logger.info("所属类名称:" + signature.getDeclaringTypeName() + "\n代理类:" + signature.getClass() + "\n方法名称:" + signature.getName() + "\n所属类:" + signature.getDeclaringType()); - Object[] args = point.getArgs(); - logger.info("参数是:" + JSON.toJSONString(args)); - logger.info("被织入的对象是:" + point.getTarget()); - logger.info("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"); - } - - /** - * 返回后通知:在连接点正常执行完后执行的通知 - */ - @AfterReturning("logaa1()") - public void afterReturningAdvice() { - logger.info("LoggerHandlerAop.afterReturningAdvice...time:" + DateUtil.now()); - } - - /** - * 抛出异常后通知:在连接节点抛出异常退出时执行的通知 - */ - @AfterThrowing("logaa1()") - public void afterThrowingAdvice() { - logger.info("LoggerHandlerAop.afterThrowingAdvice...time:" + DateUtil.now()); - } - - /** - * 后置通知:当某连接节点退出的时候执行的通知(不论是正常返回还是异常退出) - */ - @After("logaa1()") - public void afterFinallyAdvice() { - logger.info("LoggerHandlerAop.afterFinallyAdvice...time:" + DateUtil.now()); - } - - /** - * 环绕通知:包围一个连接点(join point)的通知 - * - * @param pjp - * @return - */ - @Around("logaa1()") - public Object aroundAdvice(ProceedingJoinPoint pjp) { - logger.info("LoggerHandlerAop.aroundAdvice...time:" + DateUtil.now()); - Object obj = null; - try { - System.out.println("MoocAspect around 1."); - obj = pjp.proceed(); - System.out.println("MoocAspect around 2."); - } catch (Throwable e) { - e.printStackTrace(); - } - return obj; - } + @Before("logaa1()") + public void beforeAdvice(JoinPoint point) { + logger.info("SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS"); + logger.info("LoggerHandlerAop.beforeAdvice...time:" + DateUtil.now()); + Signature signature = point.getSignature(); + logger.info("所属类名称:" + signature.getDeclaringTypeName() + "\n代理类:" + signature.getClass() + "\n方法名称:" + signature.getName() + "\n所属类:" + signature.getDeclaringType()); + Object[] args = point.getArgs(); + logger.info("参数是:" + JSON.toJSONString(args)); + logger.info("被织入的对象是:" + point.getTarget()); + logger.info("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"); + } + + /** + * 返回后通知:在连接点正常执行完后执行的通知 + */ + @AfterReturning("logaa1()") + public void afterReturningAdvice() { + logger.info("LoggerHandlerAop.afterReturningAdvice...time:" + DateUtil.now()); + } + + /** + * 抛出异常后通知:在连接节点抛出异常退出时执行的通知 + */ + @AfterThrowing("logaa1()") + public void afterThrowingAdvice() { + logger.info("LoggerHandlerAop.afterThrowingAdvice...time:" + DateUtil.now()); + } + + /** + * 后置通知:当某连接节点退出的时候执行的通知(不论是正常返回还是异常退出) + */ + @After("logaa1()") + public void afterFinallyAdvice() { + logger.info("LoggerHandlerAop.afterFinallyAdvice...time:" + DateUtil.now()); + } + + /** + * 环绕通知:包围一个连接点(join point)的通知 + * 可以实现改变方法参数并执行方法 + * @param pjp + * @return + */ + @Around(value = "logaa1()") + public Object aroundAdvice(ProceedingJoinPoint pjp) { + logger.info("LoggerHandlerAop.aroundAdvice...time:" + DateUtil.now()); + Object obj = null; + try { + // 获取方法参数信息 + Object[] args = pjp.getArgs(); + + System.out.println("MoocAspect around 1."); + obj = pjp.proceed(); + System.out.println("MoocAspect around 2."); + } catch (Throwable e) { + e.printStackTrace(); + } + return obj; + } } diff --git a/spring-boot-9-JavaMailSender/.gitignore b/spring-boot-9-JavaMailSender/.gitignore index 28972e5..bec3fb0 100644 --- a/spring-boot-9-JavaMailSender/.gitignore +++ b/spring-boot-9-JavaMailSender/.gitignore @@ -1,4 +1,5 @@ .settings/ target/ .classpath -.project \ No newline at end of file +.project +*.iml \ No newline at end of file diff --git a/spring-boot-9-JavaMailSender/spring-boot-9-JavaMailSender.iml b/spring-boot-9-JavaMailSender/spring-boot-9-JavaMailSender.iml deleted file mode 100644 index f814062..0000000 --- a/spring-boot-9-JavaMailSender/spring-boot-9-JavaMailSender.iml +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/static/111111.png b/static/111111.png new file mode 100644 index 0000000..15fa084 Binary files /dev/null and b/static/111111.png differ