diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..73f69e0
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..28a804d
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..c5de9b7
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/ssh_manage.iml b/.idea/ssh_manage.iml
new file mode 100644
index 0000000..5e764c4
--- /dev/null
+++ b/.idea/ssh_manage.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..d3d53c9
--- /dev/null
+++ b/README.md
@@ -0,0 +1,71 @@
+# ssh_manage
+go版本多用户webssh管理工具
+
+项目仅用于学习交流,未经允许禁止任何其他用途
+
+ssh2ws部分代码修改自https://github.com/hequan2017/go-webssh
+
+服务端不保存用户明文密码,且不保存解密秘钥,如需对其他用户开放,请不要修改此部分代码,以免造成不必要的损失!
+
+
+## 开发框架
+Gin + gorm
+
+##开发计划
+✔ ssh功能
+
+× 服务器文件管理
+
+## 在线演示
+[点击进入SSH云管理平台](https://www.do18.cn)
+
+##环境
+> Mysql
+> Redis
+> Go
+
+##配置文件
+> 修改config.toml的相关参数,短信接口使用阿里云短信
+```toml
+#配置文件
+[Web]
+model = "release" #debug release test
+port = "0.0.0.0:8082" #服务要运行的端口
+
+[Database]
+host = "127.0.0.1"
+port = 3306
+username = "root" #数据库账号
+password = "root" #数据库密码
+dbname = "ssh" #数据库名
+poolsize = 10 #Mysql连接池大小
+
+[Redis]
+host = "127.0.0.1"
+port = 6379
+password = "" #没有则不填
+poolsize = 10 #Redis连接池大小
+
+[Alisms]
+accessid = "—"
+accesskey = "-"
+signname = "-" #短信签名
+template = "-" #模板代码
+
+```
+##运行
+###(Mysql会在首次使用时自动初始化)
+```shell script
+go build & ./ssh_manage
+go run server.go
+```
+
+## 前端
+> Lauyi + Xterm.js
+
+
+##补充说明
+如需要使用Nginx等进行反代,请确保可以正常代理websocket
+
+##免责声明
+本软件按“原样”提供,不提供任何形式的明示或暗示担保,包括但不限于对适销性,特定目的的适用性和非侵权性的担保。无论是由于软件,使用或其他方式产生的,与之有关或与之有关的合同,侵权或其他形式的任何索赔,损害或其他责任,作者或版权所有者概不负责。
diff --git a/common/aes.go b/common/aes.go
new file mode 100644
index 0000000..8a8d85b
--- /dev/null
+++ b/common/aes.go
@@ -0,0 +1,65 @@
+package common
+
+import (
+ "bytes"
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/md5"
+ "encoding/base64"
+ "encoding/hex"
+)
+
+func AesEncryptCBC(origData []byte, key []byte) string {
+ // 分组秘钥
+ // NewCipher该函数限制了输入k的长度必须为16, 24或者32
+ key = Md5(key)[:24]
+ block, _ := aes.NewCipher(key)
+ blockSize := block.BlockSize() // 获取秘钥块的长度
+ origData = pkcs7Padding(origData, blockSize) // 补全码
+ //fmt.Println(blockSize)
+ blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) // 加密模式
+ //fmt.Println(string(Md5(key)[:blockSize]))
+ encrypted := make([]byte, len(origData)) // 创建数组
+ blockMode.CryptBlocks(encrypted, origData) // 加密
+ return base64.StdEncoding.EncodeToString(encrypted)
+}
+func AesDecryptCBC(enc string, key []byte) string {
+ key = Md5(key)[:24]
+ encrypted,_ := base64.StdEncoding.DecodeString(enc)
+ block, _ := aes.NewCipher(key) // 分组秘钥
+ blockSize := block.BlockSize() // 获取秘钥块的长度
+ blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) // 加密模式
+ decrypted := make([]byte, len(encrypted)) // 创建数组
+ blockMode.CryptBlocks(decrypted, encrypted) // 解密
+ decrypted = pkcs7UnPadding(decrypted) // 去除补全码
+ return string(decrypted)
+}
+func pkcs5Padding(ciphertext []byte, blockSize int) []byte {
+ padding := blockSize - len(ciphertext)%blockSize
+ padtext := bytes.Repeat([]byte{byte(padding)}, padding)
+ return append(ciphertext, padtext...)
+}
+func pkcs5UnPadding(origData []byte) []byte {
+ length := len(origData)
+ unpadding := int(origData[length-1])
+ return origData[:(length - unpadding)]
+}
+
+func pkcs7Padding(ciphertext []byte, blockSize int) []byte {
+ padding := blockSize - len(ciphertext)%blockSize
+ padtext := bytes.Repeat([]byte{byte(padding)}, padding)
+ return append(ciphertext, padtext...)
+}
+
+func pkcs7UnPadding(origData []byte) []byte {
+ length := len(origData)
+ unpadding := int(origData[length-1])
+ return origData[:(length - unpadding)]
+}
+
+func Md5(str []byte) []byte {
+ h := md5.New()
+ h.Write(str)
+ //fmt.Println(hex.EncodeToString(h.Sum(nil)))
+ return []byte(hex.EncodeToString(h.Sum(nil)))
+}
diff --git a/common/config.go b/common/config.go
new file mode 100644
index 0000000..805d0c7
--- /dev/null
+++ b/common/config.go
@@ -0,0 +1 @@
+package common
diff --git a/common/core/helper.go b/common/core/helper.go
new file mode 100644
index 0000000..5075e80
--- /dev/null
+++ b/common/core/helper.go
@@ -0,0 +1,33 @@
+package core
+
+import (
+ "github.com/gin-gonic/gin"
+ "github.com/gorilla/websocket"
+ "log"
+ "time"
+)
+
+func JsonError(c *gin.Context, msg interface{}) {
+ c.AbortWithStatusJSON(200, gin.H{"ok": false, "msg": msg})
+}
+
+func HandleError(c *gin.Context, err error) bool {
+ if err != nil {
+ //logrus.WithError(err).Error("gin context http handler error")
+ JsonError(c, err.Error())
+ return true
+ }
+ return false
+}
+
+func WshandleError(ws *websocket.Conn, err error) bool {
+ if err != nil {
+ log.Println("handler ws ERROR:",err.Error())
+ dt := time.Now().Add(time.Second)
+ if err := ws.WriteControl(websocket.CloseMessage, []byte(err.Error()), dt); err != nil {
+ log.Println("websocket writes control message failed:",err.Error())
+ }
+ return true
+ }
+ return false
+}
diff --git a/common/core/server.go b/common/core/server.go
new file mode 100644
index 0000000..c07ddc6
--- /dev/null
+++ b/common/core/server.go
@@ -0,0 +1,8 @@
+package core
+
+type Server struct {
+ Ip string
+ Port int
+ User string
+ Passwd string
+}
\ No newline at end of file
diff --git a/common/core/ssh.go b/common/core/ssh.go
new file mode 100644
index 0000000..7ddfeb7
--- /dev/null
+++ b/common/core/ssh.go
@@ -0,0 +1,102 @@
+package core
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "github.com/mitchellh/go-homedir"
+ "golang.org/x/crypto/ssh"
+ "io/ioutil"
+ "log"
+ "os"
+ "strings"
+ "time"
+)
+
+func NewSshClient(server Server) (*ssh.Client, error) {
+ config := &ssh.ClientConfig{
+ Timeout: time.Second * 5,
+ User: server.User,
+ HostKeyCallback: ssh.InsecureIgnoreHostKey(), //这个可以, 但是不够安全
+ //HostKeyCallback: hostKeyCallBackFunc(h.Host),
+ }
+ //if h.Type == "password" {
+ config.Auth = []ssh.AuthMethod{ssh.Password(server.Passwd)}
+ //} else {
+ // config.Auth = []ssh.AuthMethod{publicKeyAuthFunc(h.Key)}
+ //}
+ addr := fmt.Sprintf("%s:%d", server.Ip, server.Port)
+ c, err := ssh.Dial("tcp", addr, config)
+ if err != nil {
+ return nil, err
+ }
+ return c, nil
+}
+func hostKeyCallBackFunc(host string) ssh.HostKeyCallback {
+ hostPath, err := homedir.Expand("~/.ssh/known_hosts")
+ if err != nil {
+ log.Fatal("find known_hosts's home dir failed", err)
+ }
+ file, err := os.Open(hostPath)
+ if err != nil {
+ log.Fatal("can't find known_host file:", err)
+ }
+ defer file.Close()
+
+ scanner := bufio.NewScanner(file)
+ var hostKey ssh.PublicKey
+ for scanner.Scan() {
+ fields := strings.Split(scanner.Text(), " ")
+ if len(fields) != 3 {
+ continue
+ }
+ if strings.Contains(fields[0], host) {
+ var err error
+ hostKey, _, _, _, err = ssh.ParseAuthorizedKey(scanner.Bytes())
+ if err != nil {
+ log.Fatalf("error parsing %q: %v", fields[2], err)
+ }
+ break
+ }
+ }
+ if hostKey == nil {
+ log.Fatalf("no hostkey for %s,%v", host, err)
+ }
+ return ssh.FixedHostKey(hostKey)
+}
+
+func publicKeyAuthFunc(kPath string) ssh.AuthMethod {
+ keyPath, err := homedir.Expand(kPath)
+ if err != nil {
+ log.Fatal("find key's home dir failed", err)
+ }
+ key, err := ioutil.ReadFile(keyPath)
+ if err != nil {
+ log.Fatal("ssh key file read failed", err)
+ }
+ // Create the Signer for this private key.
+ signer, err := ssh.ParsePrivateKey(key)
+ if err != nil {
+ log.Fatal("ssh key signer failed", err)
+ }
+ return ssh.PublicKeys(signer)
+}
+func runCommand(client *ssh.Client, command string) (stdout string, err error) {
+ session, err := client.NewSession()
+ if err != nil {
+ //log.Print(err)
+ return
+ }
+ defer session.Close()
+
+ var buf bytes.Buffer
+ session.Stdout = &buf
+ err = session.Run(command)
+ if err != nil {
+ //log.Print(err)
+ return
+ }
+ stdout = string(buf.Bytes())
+
+ return
+}
diff --git a/common/core/ssh_shell_conn.go b/common/core/ssh_shell_conn.go
new file mode 100644
index 0000000..357ec63
--- /dev/null
+++ b/common/core/ssh_shell_conn.go
@@ -0,0 +1,196 @@
+package core
+
+import (
+ "bytes"
+ "encoding/json"
+ "github.com/gorilla/websocket"
+ "golang.org/x/crypto/ssh"
+ "io"
+ "log"
+ "sync"
+ "time"
+)
+
+// copy data from WebSocket to ssh server
+// and copy data from ssh server to WebSocket
+
+// write data to WebSocket
+// the data comes from ssh server.
+type wsBufferWriter struct {
+ buffer bytes.Buffer
+ mu sync.Mutex
+}
+
+// implement Write interface to write bytes from ssh server into bytes.Buffer.
+func (w *wsBufferWriter) Write(p []byte) (int, error) {
+ w.mu.Lock()
+ defer w.mu.Unlock()
+ return w.buffer.Write(p)
+}
+
+const (
+ wsMsgCmd = "cmd"
+ wsMsgResize = "resize"
+)
+
+type wsMsg struct {
+ Type string `json:"type"`
+ Cmd string `json:"cmd"`
+ Cols int `json:"cols"`
+ Rows int `json:"rows"`
+}
+
+// connect to ssh server using ssh session.
+type SshConn struct {
+ // calling Write() to write data into ssh server
+ StdinPipe io.WriteCloser
+ // Write() be called to receive data from ssh server
+ ComboOutput *wsBufferWriter
+ Session *ssh.Session
+}
+
+//flushComboOutput flush ssh.session combine output into websocket response
+func flushComboOutput(w *wsBufferWriter, wsConn *websocket.Conn) error {
+ if w.buffer.Len() != 0 {
+ err := wsConn.WriteMessage(websocket.TextMessage, w.buffer.Bytes())
+ if err != nil {
+ return err
+ }
+ w.buffer.Reset()
+ }
+ return nil
+}
+
+// setup ssh shell session
+// set Session and StdinPipe here,
+// and the Session.Stdout and Session.Sdterr are also set.
+func NewSshConn(cols, rows int, sshClient *ssh.Client) (*SshConn, error) {
+ sshSession, err := sshClient.NewSession()
+ if err != nil {
+ return nil, err
+ }
+
+ // we set stdin, then we can write data to ssh server via this stdin.
+ // but, as for reading data from ssh server, we can set Session.Stdout and Session.Stderr
+ // to receive data from ssh server, and write back to somewhere.
+ stdinP, err := sshSession.StdinPipe()
+ if err != nil {
+ return nil, err
+ }
+
+ comboWriter := new(wsBufferWriter)
+ //ssh.stdout and stderr will write output into comboWriter
+ sshSession.Stdout = comboWriter
+ sshSession.Stderr = comboWriter
+
+ modes := ssh.TerminalModes{
+ ssh.ECHO: 1, // disable echo
+ ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
+ ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
+ }
+ // Request pseudo terminal
+ if err := sshSession.RequestPty("xterm", rows, cols, modes); err != nil {
+ return nil, err
+ }
+ // Start remote shell
+ if err := sshSession.Shell(); err != nil {
+ return nil, err
+ }
+ return &SshConn{StdinPipe: stdinP, ComboOutput: comboWriter, Session: sshSession}, nil
+}
+
+func (s *SshConn) Close() {
+ if s.Session != nil {
+ s.Session.Close()
+ }
+
+}
+
+//ReceiveWsMsg receive websocket msg do some handling then write into ssh.session.stdin
+func (ssConn *SshConn) ReceiveWsMsg(wsConn *websocket.Conn, exitCh chan bool) {
+ //tells other go routine quit
+ defer setQuit(exitCh)
+ for {
+ select {
+ case <-exitCh:
+ return
+ default:
+ //read websocket msg
+ _, wsData, err := wsConn.ReadMessage()
+ if err != nil {
+ log.Println(err.Error())
+ //logrus.WithError(err).Error("reading webSocket message failed")
+ return
+ }
+ //unmashal bytes into struct
+ msgObj := wsMsg{
+ Type: "cmd",
+ Cmd: "",
+ Rows: 50,
+ Cols: 180,
+ }
+ if err := json.Unmarshal(wsData, &msgObj); err != nil {
+ log.Println("unmarshal websocket message failed:",string(wsData))
+ continue
+ }
+ switch msgObj.Type {
+ case wsMsgResize:
+ //handle xterm.js size change
+ if msgObj.Cols > 0 && msgObj.Rows > 0 {
+ if err := ssConn.Session.WindowChange(msgObj.Rows, msgObj.Cols); err != nil {
+ log.Println("ssh pty change windows size failed")
+ continue
+ }
+ }
+ case wsMsgCmd:
+ //handle xterm.js stdin
+ //decodeBytes, err := base64.StdEncoding.DecodeString(msgObj.Cmd)
+ decodeBytes := []byte(msgObj.Cmd)
+ if err != nil {
+ log.Println("websock cmd string base64 decoding failed")
+ continue
+ }
+ if _, err := ssConn.StdinPipe.Write(decodeBytes); err != nil {
+ log.Println("ws cmd bytes write to ssh.stdin pipe failed")
+ return
+ }
+ }
+ }
+ }
+}
+func (ssConn *SshConn) SendComboOutput(wsConn *websocket.Conn, exitCh chan bool) {
+ //tells other go routine quit
+ defer setQuit(exitCh)
+
+ //every 120ms write combine output bytes into websocket response
+ tick := time.NewTicker(time.Millisecond * time.Duration(120))
+ //for range time.Tick(120 * time.Millisecond){}
+ defer tick.Stop()
+ for {
+ select {
+ case <-tick.C:
+ //write combine output bytes into websocket response
+ if err := flushComboOutput(ssConn.ComboOutput, wsConn); err != nil {
+ if err == io.EOF{
+ log.Println("Exit")
+ }
+ log.Println(err.Error())
+ //logrus.WithError(err).Error("ssh sending combo output to webSocket failed")
+ return
+ }
+ case <-exitCh:
+ return
+ }
+ }
+}
+
+func (ssConn *SshConn) SessionWait(quitChan chan bool) {
+ if err := ssConn.Session.Wait(); err != nil {
+ log.Println("ssh session wait failed")
+ setQuit(quitChan)
+ }
+}
+
+func setQuit(ch chan bool) {
+ ch <- true
+}
diff --git a/common/jwt.go b/common/jwt.go
new file mode 100644
index 0000000..05d23d2
--- /dev/null
+++ b/common/jwt.go
@@ -0,0 +1,47 @@
+package common
+
+import (
+ "github.com/dgrijalva/jwt-go"
+ "time"
+)
+
+var jwt_ket = []byte("ss_jwt_token")
+
+type Claims struct {
+ Userid uint
+ jwt.StandardClaims
+}
+
+func ReleaseToken(id uint) (token string, err error) {
+ expire_time := time.Now().Add(7 * 24 * time.Hour)
+ claims := &Claims{
+ Userid: id,
+ StandardClaims: jwt.StandardClaims{
+ ExpiresAt: expire_time.Unix(),
+ IssuedAt: time.Now().Unix(),
+ Issuer: "admin",
+ Subject: "user",
+ },
+ }
+ token_obj := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
+ token, err = token_obj.SignedString(jwt_ket)
+ return
+}
+
+func ParseToken(token string) (*Claims, error) {
+
+ //用于解析鉴权的声明,方法内部主要是具体的解码和校验的过程,最终返回*Token
+ tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) {
+ return jwt_ket, nil
+ })
+
+ if tokenClaims != nil {
+ // 从tokenClaims中获取到Claims对象,并使用断言,将该对象转换为我们自己定义的Claims
+ // 要传入指针,项目中结构体都是用指针传递,节省空间。
+ if claims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid {
+ return claims, nil
+ }
+ }
+ return nil, err
+
+}
diff --git a/common/sms.go b/common/sms.go
new file mode 100644
index 0000000..6a4a535
--- /dev/null
+++ b/common/sms.go
@@ -0,0 +1,44 @@
+package common
+
+import (
+ "errors"
+ "fmt"
+ "github.com/aliyun/alibaba-cloud-sdk-go/services/dysmsapi"
+ "log"
+ "math/rand"
+ "regexp"
+ "ssh_manage/config"
+ "time"
+)
+
+var aliconfig = config.Config.Alisms
+
+func VerifyMobileFormat(mobileNum string) bool {
+ regular := "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$"
+ reg := regexp.MustCompile(regular)
+ return reg.MatchString(mobileNum)
+}
+
+func Sendsms(phone string) (captcha string,err error) {
+ captcha = createCaptcha()
+ client, err := dysmsapi.NewClientWithAccessKey("cn-hangzhou", aliconfig.Accessid, aliconfig.Accesskey)
+ request := dysmsapi.CreateSendBatchSmsRequest()
+ request.Scheme = "https"
+ request.PhoneNumberJson = fmt.Sprintf("[\"%s\"]", phone)
+ request.SignNameJson = fmt.Sprintf("[\"%s\"]", aliconfig.Signname)
+ request.TemplateCode = aliconfig.Template
+ request.TemplateParamJson = fmt.Sprintf("[{\"code\":\"%s\"}]", captcha)
+ response, err := client.SendBatchSms(request)
+ //if err != nil {
+ // log.Println(err.Error())
+ //}
+ if response.Code != "OK" {
+ err = errors.New("短信服务器错误")
+ log.Println(response)
+ }
+ return
+}
+
+func createCaptcha() string {
+ return fmt.Sprintf("%08v", rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(100000000))
+}
diff --git a/common/verify.go b/common/verify.go
new file mode 100644
index 0000000..f7d0357
--- /dev/null
+++ b/common/verify.go
@@ -0,0 +1,39 @@
+package common
+
+import (
+ "fmt"
+ "github.com/garyburd/redigo/redis"
+ "log"
+ "regexp"
+ "ssh_manage/database"
+ "strings"
+)
+
+type verifyImpl interface {
+ Verify() (key, code string)
+}
+
+func Verify(v verifyImpl) (is_verify bool) {
+ phone, code := v.Verify()
+ cache := database.Cache.Get()
+ defer cache.Close()
+ s_code, err := redis.String(cache.Do("GET", phone))
+ if err != nil {
+ log.Println("Verify Err:", err.Error())
+ return
+ }
+ if code != s_code {
+ log.Println(fmt.Sprintf("手机号:%s -- 验证码:%s 校验失败", phone, code))
+ return
+ }
+ return true
+}
+
+func CheckIp(ip string) bool {
+ addr := strings.Trim(ip, " ")
+ regStr := `^(([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){2}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$`
+ if match, _ := regexp.MatchString(regStr, addr); match {
+ return true
+ }
+ return false
+}
\ No newline at end of file
diff --git a/config.toml b/config.toml
new file mode 100644
index 0000000..8092af6
--- /dev/null
+++ b/config.toml
@@ -0,0 +1,24 @@
+#配置文件
+[Web]
+model = "release" #debug release test
+port = "0.0.0.0:8082" #服务要运行的端口
+
+[Database]
+host = "127.0.0.1"
+port = 3306
+username = "root" #数据库账号
+password = "root" #数据库密码
+dbname = "ssh" #数据库名
+poolsize = 10 #Mysql连接池大小
+
+[Redis]
+host = "127.0.0.1"
+port = 6379
+password = "" #没有则不填
+poolsize = 10 #Redis连接池大小
+
+[Alisms]
+accessid = "—"
+accesskey = "-"
+signname = "-" #短信签名
+template = "-" #模板代码
\ No newline at end of file
diff --git a/config/config.go b/config/config.go
new file mode 100644
index 0000000..2d469f9
--- /dev/null
+++ b/config/config.go
@@ -0,0 +1,55 @@
+package config
+
+import (
+ "github.com/BurntSushi/toml"
+ "log"
+)
+
+//订制配置文件解析载体
+type config struct {
+ Web *webset
+ Database *database
+ Redis *redis
+ Alisms *alisms
+}
+
+type alisms struct {
+ Accessid string
+ Accesskey string
+ Signname string
+ Template string
+}
+
+type redis struct {
+ //Driver string
+ Poolsize int
+ Host string
+ Port uint
+ Password string
+}
+
+//订制Database块
+type database struct {
+ //Driver string
+ Poolsize int
+ Host string
+ Port uint
+ Username string
+ Dbname string
+ Password string
+}
+
+type webset struct {
+ Model string
+ Port string
+}
+
+var Config *config = new(config)
+
+func init() {
+ //读取配置文件
+ _, err := toml.DecodeFile("config.toml", Config)
+ if err != nil {
+ log.Panic(err.Error())
+ }
+}
diff --git a/controller/add.go b/controller/add.go
new file mode 100644
index 0000000..b40eea5
--- /dev/null
+++ b/controller/add.go
@@ -0,0 +1,37 @@
+package controller
+
+import (
+ "github.com/gin-gonic/gin"
+ "ssh_manage/common"
+ "ssh_manage/database"
+ "ssh_manage/errcode"
+ "ssh_manage/model"
+ "ssh_manage/model/Apiform"
+)
+
+func Addser(c *gin.Context) {
+ var resp Apiform.Resp
+ new_token := c.MustGet("token").(string)
+ if new_token != "" { //更新Token逻辑
+ resp.Token = new_token
+ }
+ uid := c.MustGet("uid").(uint)
+ var info Apiform.Addser
+ resp.Code = errcode.C_from_err
+ resp.Msg = "数据错误"
+ if c.ShouldBind(&info) == nil {
+ if(common.CheckIp(info.Ip)){
+ db := database.Get()
+ defer db.Close()
+ result := db.DB.Create(&model.Server{Ip: info.Ip,Port: info.Port,Username: info.Username,Password: info.Password,Nickname: info.Nickname,BindUser: uid})
+ if result.RowsAffected == 1 && result.Error == nil{
+ resp.Code = errcode.C_nil_err
+ resp.Msg = "保存成功"
+ }else{
+ resp.Code = errcode.S_Db_err
+ resp.Msg = "保存失败"
+ }
+ }
+ }
+ c.JSON(200,resp)
+}
diff --git a/controller/info.go b/controller/info.go
new file mode 100644
index 0000000..d1464ea
--- /dev/null
+++ b/controller/info.go
@@ -0,0 +1,178 @@
+package controller
+
+import (
+ "github.com/Gre-Z/common/jtime"
+ "github.com/gin-gonic/gin"
+ "ssh_manage/database"
+ "ssh_manage/errcode"
+ "ssh_manage/model"
+ "ssh_manage/model/Apiform"
+ "time"
+)
+
+func Info(c *gin.Context) {
+ var resp Apiform.Resp
+ new_token := c.MustGet("token").(string)
+ if new_token != "" { //更新Token逻辑
+ resp.Token = new_token
+ }
+ uid := c.MustGet("uid").(uint)
+ var limit Apiform.Slist
+ if c.MustGet("uid").(uint) > 0 {
+ if c.ShouldBind(&limit) == nil {
+ //var user model.User
+ var list Apiform.List_resp
+ var server model.Server
+ server.BindUser = uid
+ db := database.Get()
+ defer db.Close()
+ db.DB.Model(&model.Server{}).Where(&server).Count(&list.Count).Offset((limit.Page - 1) * limit.Limit).Limit(limit.Limit).Find(&list.List)
+ //db.DB.Model(&user).Related(&servers,"Servers").Count(&list.Count).Offset((limit.Page - 1) * limit.Limit).Limit(limit.Limit).Find(&list.List)
+ resp.Code = 200
+ resp.Data = list
+ resp.Msg = "查询成功"
+ } else {
+ resp.Code = errcode.C_from_err
+ resp.Msg = "数据格式错误"
+ }
+ } else {
+ resp.Code = errcode.S_Verify_err
+ resp.Msg = "Token信息错误"
+ }
+ c.JSON(200, resp)
+}
+
+func UpdataNick(c *gin.Context) {
+ var resp Apiform.Resp
+ var edit Apiform.Edit
+ new_token := c.MustGet("token").(string)
+ if new_token != "" { //更新Token逻辑
+ resp.Token = new_token
+ }
+ uid := c.MustGet("uid").(uint)
+ //nickname, name_exist := c.GetPostForm("nickname")
+ //sidstr, sid_exist := c.GetPostForm("id")
+ //sid, err := strconv.Atoi(sidstr)
+ //log.Println(c.ShouldBind(&edit))
+ if c.ShouldBind(&edit) == nil {
+ //server.Nickname = nickname
+ var server model.Server
+ server.ID = edit.ID
+ server.BindUser = uid
+ db := database.Get()
+ defer db.Close()
+ result := db.DB.Model(&model.Server{}).Where(&server).Update(model.Server{Nickname: edit.Nickname, Ip: edit.Ip, Port: edit.Port, Username: edit.Username})
+ if result.RowsAffected == 1 && result.Error == nil {
+ resp.Code = errcode.C_nil_err
+ resp.Msg = "保存成功"
+ } else {
+ resp.Code = errcode.S_Db_err
+ resp.Msg = "修改失败"
+ }
+ } else {
+ resp.Code = errcode.C_from_err
+ resp.Msg = "提交字段错误"
+ }
+ c.JSON(200, resp)
+}
+
+func Resetpass(c *gin.Context) {
+ var resp Apiform.Resp
+ var edit Apiform.EditPass
+ new_token := c.MustGet("token").(string)
+ if new_token != "" { //更新Token逻辑
+ resp.Token = new_token
+ }
+ uid := c.MustGet("uid").(uint)
+ //nickname, name_exist := c.GetPostForm("nickname")
+ //sidstr, sid_exist := c.GetPostForm("id")
+ //sid, err := strconv.Atoi(sidstr)
+ //log.Println(c.ShouldBind(&edit))
+ if c.ShouldBind(&edit) == nil {
+ //server.Nickname = nickname
+ var server model.Server
+ server.ID = edit.ID
+ server.BindUser = uid
+ db := database.Get()
+ defer db.Close()
+ result := db.DB.Model(&model.Server{}).Where(&server).Update(model.Server{Password: edit.Password})
+ if result.RowsAffected == 1 && result.Error == nil {
+ resp.Code = errcode.C_nil_err
+ resp.Msg = "保存成功"
+ } else {
+ resp.Code = errcode.S_Db_err
+ resp.Msg = "修改失败"
+ }
+ } else {
+ resp.Code = errcode.C_from_err
+ resp.Msg = "提交字段错误"
+ }
+ c.JSON(200, resp)
+}
+
+func Del(c *gin.Context) {
+ var resp Apiform.Resp
+ var del Apiform.Edit
+ new_token := c.MustGet("token").(string)
+ if new_token != "" { //更新Token逻辑
+ resp.Token = new_token
+ }
+ uid := c.MustGet("uid").(uint)
+ if c.ShouldBind(&del) == nil {
+ //server.Nickname = nickname
+ var server model.Server
+ server.ID = del.ID
+ server.BindUser = uid
+ db := database.Get()
+ defer db.Close()
+ result := db.DB.Where(&server).Delete(&model.Server{})
+ if result.RowsAffected == 1 && result.Error == nil {
+ resp.Code = errcode.C_nil_err
+ resp.Msg = "删除成功"
+ } else {
+ resp.Code = errcode.S_Db_err
+ resp.Msg = "操作失败"
+ }
+ } else {
+ resp.Code = errcode.C_from_err
+ resp.Msg = "提交字段错误"
+ }
+ c.JSON(200, resp)
+}
+
+func GetTerm(c *gin.Context) {
+ var resp Apiform.Resp
+ var term Apiform.GetTerm
+ new_token := c.MustGet("token").(string)
+ if new_token != "" { //更新Token逻辑
+ resp.Token = new_token
+ }
+ uid := c.MustGet("uid").(uint)
+ resp.Code = errcode.C_from_err
+ resp.Msg = "表单错误"
+ if c.ShouldBind(&term) == nil {
+ var server model.Server
+ server.ID = term.ID
+ server.BindUser = uid
+ db := database.Get()
+ defer db.Close()
+ result := db.DB.Model(&model.Server{}).First(&server)
+ if result.RowsAffected == 1 && result.Error == nil {
+ db.DB.Model(&model.Server{}).Where(&server).Update(model.Server{BeforeTime: jtime.JsonTime{time.Now()}})
+ sid, err := term.Decode(server)
+ //log.Println(sid)
+ if err == nil {
+ resp.Code = errcode.C_nil_err
+ resp.Data = sid
+ resp.Msg = "OK"
+ } else {
+ resp.Code = errcode.S_Verify_err
+ resp.Msg = "秘钥解密失败"
+ }
+ } else {
+ resp.Code = errcode.S_Db_err
+ resp.Msg = "服务器信息检索失败"
+ }
+ }
+ c.JSON(200,resp)
+}
diff --git a/controller/login.go b/controller/login.go
new file mode 100644
index 0000000..c614dbb
--- /dev/null
+++ b/controller/login.go
@@ -0,0 +1,44 @@
+package controller
+
+import (
+ "github.com/gin-gonic/gin"
+ "ssh_manage/common"
+ "ssh_manage/database"
+ "ssh_manage/errcode"
+ "ssh_manage/model"
+ "ssh_manage/model/Apiform"
+)
+
+func Login(c *gin.Context) {
+ //common.Sendsms()
+ //log.Print(db.DB.Exec("select * from products"))
+ //token := c.MustGet("token").(string)
+ //c.JSON(200, gin.H{"token": token})
+ var resp Apiform.Resp
+ resp.Code = errcode.C_from_err
+ resp.Msg = "手机号和验证码不能为空!"
+ var user Apiform.Login
+ if c.ShouldBind(&user) == nil {
+ if common.Verify(&user) {
+ var userinfo model.User
+ db := database.Get()
+ defer db.Close()
+ db.DB.Where(model.User{Phone: user.Phone}).FirstOrCreate(&userinfo)
+ new_token, err := common.ReleaseToken(userinfo.ID)
+ if err == nil {
+ resp.Code = errcode.C_nil_err
+ resp.Msg = "登陆成功"
+ resp.Data = userinfo
+ resp.Token = new_token
+ } else {
+ resp.Code = errcode.S_auth_err
+ resp.Msg = "Token创建失败"
+ }
+ } else {
+ resp.Code = errcode.S_Verify_err
+ resp.Msg = "验证码校验失败"
+ }
+ }
+ //log.Printf(c.ClientIP())
+ c.JSON(200, resp)
+}
diff --git a/controller/middleware/Auth.go b/controller/middleware/Auth.go
new file mode 100644
index 0000000..43433bd
--- /dev/null
+++ b/controller/middleware/Auth.go
@@ -0,0 +1,64 @@
+package middleware
+
+import (
+ "github.com/gin-gonic/gin"
+ "ssh_manage/common"
+ "ssh_manage/database"
+ "ssh_manage/errcode"
+ "ssh_manage/model"
+ "ssh_manage/model/Apiform"
+ "strings"
+ "time"
+)
+
+func Auth() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ var resp Apiform.Resp
+ jwt_token := c.GetHeader("Authorization")
+ //log.Println(jwt_token)
+ //log.Println(strings.HasPrefix(jwt_token, "Bearer "))
+ if jwt_token == "" || !strings.HasPrefix(jwt_token, "Bearer ") {
+ resp.Code = errcode.S_auth_fmt_err
+ resp.Msg = "Token不正确"
+ c.JSON(200, resp)
+ c.Abort()
+ return
+ }
+ jwt_token = jwt_token[7:]
+ claims, err := common.ParseToken(jwt_token)
+ if err != nil {
+ resp.Code = errcode.S_auth_err
+ resp.Msg = "Token错误,请重新登录"
+ c.JSON(200, resp)
+ c.Abort()
+ return
+ }
+ valid := claims.Valid()
+ if valid != nil {
+ resp.Code = errcode.S_auth_err
+ resp.Msg = "用户登录超时,请重新登录"
+ c.JSON(200, resp)
+ c.Abort()
+ return
+ }
+ var userinfo model.User
+ db := database.Get()
+ defer db.Close()
+ userinfo.ID = claims.Userid
+ db.DB.Where(userinfo).First(&userinfo)
+ if userinfo.Phone == 0 {
+ resp.Code = errcode.S_auth_err
+ resp.Msg = "用户不存在,请重新登录"
+ c.JSON(200, resp)
+ c.Abort()
+ return
+ }
+ c.Set("uid", claims.Userid)
+ c.Set("token", "")
+ new_token, err := common.ReleaseToken(claims.Userid)
+ if time.Now().Add(24*time.Hour).Unix() > claims.ExpiresAt { //如果过期时间小于一天,则更新客户端token
+ c.Set("token", new_token)
+ }
+ c.Next()
+ }
+}
diff --git a/controller/middleware/ws.go b/controller/middleware/ws.go
new file mode 100644
index 0000000..7a48f16
--- /dev/null
+++ b/controller/middleware/ws.go
@@ -0,0 +1,46 @@
+package middleware
+
+import (
+ "fmt"
+ "github.com/gin-gonic/gin"
+ "log"
+ "net/http"
+ "strings"
+)
+
+func Cors() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ log.Println("Ws Md")
+ method := c.Request.Method //请求方法
+ origin := c.Request.Header.Get("Origin") //请求头部
+ var headerKeys []string // 声明请求头keys
+ for k, _ := range c.Request.Header {
+ headerKeys = append(headerKeys, k)
+ }
+ headerStr := strings.Join(headerKeys, ", ")
+ if headerStr != "" {
+ headerStr = fmt.Sprintf("access-control-allow-origin, access-control-allow-headers, %s", headerStr)
+ } else {
+ headerStr = "access-control-allow-origin, access-control-allow-headers"
+ }
+ if origin != "" {
+ c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
+ c.Header("Access-Control-Allow-Origin", "*") // 这是允许访问所有域
+ c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE") //服务器支持的所有跨域请求的方法,为了避免浏览次请求的多次'预检'请求
+ // header的类型
+ c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,X_Requested_With,Accept, Origin, Host, Connection, Accept-Encoding, Accept-Language,DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Pragma")
+ // 允许跨域设置 可以返回其他子段
+ c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma,FooBar") // 跨域关键设置 让浏览器可以解析
+ c.Header("Access-Control-Max-Age", "172800") // 缓存请求信息 单位为秒
+ c.Header("Access-Control-Allow-Credentials", "false") // 跨域请求是否需要带cookie信息 默认设置为true
+ c.Set("content-type", "application/json") // 设置返回格式是json
+ }
+
+ //放行所有OPTIONS方法
+ if method == "OPTIONS" {
+ c.JSON(http.StatusOK, "Options Request!")
+ }
+ // 处理请求
+ c.Next() // 处理请求
+ }
+}
diff --git a/controller/send.go b/controller/send.go
new file mode 100644
index 0000000..38244fb
--- /dev/null
+++ b/controller/send.go
@@ -0,0 +1,30 @@
+package controller
+
+import (
+ "github.com/gin-gonic/gin"
+ "ssh_manage/common"
+ "ssh_manage/errcode"
+ "ssh_manage/model/Apiform"
+)
+
+func Send(c *gin.Context) {
+ var resp Apiform.Resp
+ var send Apiform.Send
+ resp.Code = errcode.C_phone_err
+ resp.Msg = "手机号未提交!"
+ if c.ShouldBind(&send) == nil {
+ if common.VerifyMobileFormat(send.Phone) {
+ if err := send.SendCaptcha(c.ClientIP()); err != nil {
+ resp.Code = errcode.S_send_err
+ resp.Msg = err.Error()
+ } else {
+ resp.Code = errcode.C_nil_err
+ resp.Msg = "发送成功!"
+ }
+ } else {
+ resp.Code = errcode.C_phone_err
+ resp.Msg = "手机号验证失败!"
+ }
+ }
+ c.JSON(200, resp)
+}
diff --git a/controller/term.go b/controller/term.go
new file mode 100644
index 0000000..d71dbe5
--- /dev/null
+++ b/controller/term.go
@@ -0,0 +1,130 @@
+package controller
+
+import (
+ "encoding/json"
+ "fmt"
+ "github.com/garyburd/redigo/redis"
+ "github.com/gin-gonic/gin"
+ "github.com/gorilla/websocket"
+ "log"
+ "net/http"
+ "ssh_manage/common"
+ "ssh_manage/common/core"
+ "ssh_manage/database"
+ "ssh_manage/model/Apiform"
+ "strconv"
+)
+
+var upGrader = websocket.Upgrader{
+ ReadBufferSize: 1024,
+ WriteBufferSize: 1024 * 1024 * 10,
+ CheckOrigin: func(r *http.Request) bool {
+ return true
+ },
+}
+
+type Auth_msg struct {
+ Type string `json:"type"`
+ Token string `json:"token"`
+}
+
+// handle webSocket connection.
+// first,we establish a ssh connection to ssh server when a webSocket comes;
+// then we deliver ssh data via ssh connection between browser and ssh server.
+// That is, read webSocket data from browser (e.g. 'ls' command) and send data to ssh server via ssh connection;
+// the other hand, read returned ssh data from ssh server and write back to browser via webSocket API.
+func WsSsh(c *gin.Context) {
+ wsConn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
+ if core.HandleError(c, err) {
+ return
+ }
+ defer wsConn.Close()
+
+ cols, err := strconv.Atoi(c.DefaultQuery("cols", "120"))
+ if core.WshandleError(wsConn, err) {
+ return
+ }
+ rows, err := strconv.Atoi(c.DefaultQuery("rows", "32"))
+ if core.WshandleError(wsConn, err) {
+ return
+ }
+
+ var ser_info Apiform.SerInfo //接收反序列化数据
+ var auth Apiform.WsAuth
+
+ if c.ShouldBindUri(&auth) != nil{
+ wsConn.WriteMessage(websocket.TextMessage,[]byte("参数错误\r\n"))
+ wsConn.Close()
+ return
+ }
+
+ for {
+ _, wsData, err := wsConn.ReadMessage()
+ if err != nil {
+ log.Println(err.Error())
+ wsConn.Close()
+ //logrus.WithError(err).Error("reading webSocket message failed")
+ return
+ }
+ //unmashal bytes into struct
+ msgObj := Auth_msg{}
+ if err := json.Unmarshal(wsData, &msgObj); err != nil {
+ log.Println("Auth : unmarshal websocket message failed:", string(wsData))
+ continue
+ }
+ token := msgObj.Token
+ claims, err := common.ParseToken(token)
+ valid := claims.Valid()
+ if valid != nil || err != nil {
+ wsConn.WriteMessage(websocket.TextMessage, []byte("身份验证失败\r\n"))
+ wsConn.Close()
+ return
+ }
+ cache := database.Cache.Get()
+ defer cache.Close()
+ //log.Println(auth)
+ s_info,err := redis.Bytes(cache.Do("GET", auth.Sid))
+ //log.Println(string(s_info))
+ if err != nil || len(s_info) == 0{
+ wsConn.WriteMessage(websocket.TextMessage, []byte("连接超时,请重试!\r\n"))
+ wsConn.Close()
+ return
+ }
+ if json.Unmarshal(s_info,&ser_info) != nil{
+ wsConn.WriteMessage(websocket.TextMessage, []byte("服务器信息获取失败,请重试!\r\n"))
+ wsConn.Close()
+ return
+ }
+ //log.Println(ser_info)
+ if claims.Userid != ser_info.BindUser{ //验证权限
+ wsConn.WriteMessage(websocket.TextMessage, []byte("权限验证失败,请重试!\r\n"))
+ wsConn.Close()
+ return
+ }
+ break
+ //break
+ }
+ client, err := core.NewSshClient(core.Server{ser_info.Ip, ser_info.Port, ser_info.Username, ser_info.Password})
+ if core.WshandleError(wsConn, err) {
+ return
+ }
+ defer client.Close()
+ //startTime := time.Now()
+ ssConn, err := core.NewSshConn(cols, rows, client)
+
+ if core.WshandleError(wsConn, err) {
+ return
+ }
+ defer ssConn.Close()
+
+ quitChan := make(chan bool, 2)
+
+ // most messages are ssh output, not webSocket input
+ go ssConn.ReceiveWsMsg(wsConn, quitChan)
+ go ssConn.SendComboOutput(wsConn, quitChan)
+ //go ssConn.SessionWait(quitChan)
+
+ <-quitChan //任意协程退出则结束
+ fmt.Println("Exit")
+ log.Println("websocket finished")
+}
diff --git a/database/cache.go b/database/cache.go
new file mode 100644
index 0000000..452443d
--- /dev/null
+++ b/database/cache.go
@@ -0,0 +1,43 @@
+package database
+
+import (
+ "fmt"
+ redigo "github.com/garyburd/redigo/redis"
+ "ssh_manage/config"
+ "time"
+)
+
+var redis_conf = config.Config.Redis
+
+var Cache *redigo.Pool
+
+func init() {
+ var addr = fmt.Sprintf("%s:%d",redis_conf.Host,redis_conf.Port)
+ var password = redis_conf.Password
+ Cache = poolInitRedis(addr, password)
+}
+
+func poolInitRedis(server string, password string) *redigo.Pool {
+ return &redigo.Pool{
+ MaxIdle: 2, //空闲数
+ IdleTimeout: 240 * time.Second,
+ MaxActive: redis_conf.Poolsize, //最大数
+ Dial: func() (redigo.Conn, error) {
+ c, err := redigo.Dial("tcp", server)
+ if err != nil {
+ return nil, err
+ }
+ if password != "" {
+ if _, err := c.Do("AUTH", password); err != nil {
+ c.Close()
+ return nil, err
+ }
+ }
+ return c, err
+ },
+ TestOnBorrow: func(c redigo.Conn, t time.Time) error {
+ _, err := c.Do("PING")
+ return err
+ },
+ }
+}
diff --git a/database/conn.go b/database/conn.go
new file mode 100644
index 0000000..95488b6
--- /dev/null
+++ b/database/conn.go
@@ -0,0 +1,42 @@
+package database
+
+import (
+ "fmt"
+ "github.com/jinzhu/gorm"
+ _ "github.com/jinzhu/gorm/dialects/mysql"
+ "log"
+ "ssh_manage/config"
+ "ssh_manage/model"
+)
+
+var dbconf = config.Config.Database
+
+var pool *sqlpool
+
+type Mydb struct {
+ DB *gorm.DB
+}
+
+func init() {
+ pool = newpool(newDb, dbconf.Poolsize)
+}
+
+func newDb() *gorm.DB {
+ db, err := gorm.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local",dbconf.Username,dbconf.Password,dbconf.Host,dbconf.Port,dbconf.Dbname))
+ if err != nil {
+ log.Panicf("db open err :%s", err.Error())
+ }
+ if !db.HasTable(&model.User{}){
+ log.Println("init table")
+ db.CreateTable(&model.Server{},&model.User{})
+ }
+ return db
+}
+
+func (s *Mydb) Close() {
+ pool.put(s.DB)
+}
+
+func Get() *Mydb {
+ return &Mydb{pool.get()}
+}
diff --git a/database/pool.go b/database/pool.go
new file mode 100644
index 0000000..e235e18
--- /dev/null
+++ b/database/pool.go
@@ -0,0 +1,46 @@
+package database
+
+import (
+ "github.com/jinzhu/gorm"
+ "sync"
+)
+
+//type pool interface {
+// newpool(newdb func()*gorm.DB,size int) *sqlpool
+// get() (db *gorm.DB)
+// put(db *gorm.DB)
+//}
+
+type sqlpool struct {
+ new func() *gorm.DB
+ db []*gorm.DB
+ sync.Mutex
+}
+
+func newpool(newdb func() *gorm.DB, size int) *sqlpool {
+ return &sqlpool{newdb, make([]*gorm.DB, 0, size), sync.Mutex{}}
+}
+
+func (s *sqlpool) get() (db *gorm.DB) {
+ s.Lock()
+ defer s.Unlock()
+ //log.Printf("before len:%d", len(s.db))
+ if len(s.db) > 0 {
+ db = s.db[len(s.db)-1]
+ s.db = s.db[:len(s.db)-1]
+ } else {
+ db = s.new()
+ }
+ //log.Printf("after len:%d", len(s.db))
+ return db
+}
+
+func (s *sqlpool) put(db *gorm.DB) {
+ s.Lock()
+ defer s.Unlock()
+ if len(s.db) < cap(s.db) {
+ s.db = append(s.db, db)
+ } else {
+ db.Close()
+ }
+}
diff --git a/errcode/Err.go b/errcode/Err.go
new file mode 100644
index 0000000..a967ab9
--- /dev/null
+++ b/errcode/Err.go
@@ -0,0 +1,13 @@
+package errcode
+
+const (
+ C_nil_err = 200 //成功
+ C_from_err = 100 //表单错误
+ C_phone_err = 101 //手机号错误
+ C_code_err = 102 //验证码错误
+ S_send_err = 300 //发送验证码错误
+ S_auth_err = 301 //Token权限校验失败
+ S_auth_fmt_err = 302 //Header Token格式错误
+ S_Verify_err = 303 //验证码校验失败
+ S_Db_err = 304
+)
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..728a5ad
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,17 @@
+module ssh_manage
+
+go 1.14
+
+require (
+ github.com/BurntSushi/toml v0.3.1
+ github.com/Gre-Z/common v0.0.0-20191024025434-2dbc6bd196f9
+ github.com/aliyun/alibaba-cloud-sdk-go v1.61.623
+ github.com/dgrijalva/jwt-go v3.2.0+incompatible
+ github.com/garyburd/redigo v1.6.2
+ github.com/gin-gonic/gin v1.6.3
+ github.com/gorilla/websocket v1.4.2
+ github.com/jinzhu/gorm v1.9.16
+ github.com/mitchellh/go-homedir v1.1.0
+ github.com/satori/go.uuid v1.2.0
+ golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..f293bbb
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,113 @@
+github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/Gre-Z/common v0.0.0-20191024025434-2dbc6bd196f9 h1:q+nKJ4E5tIiGVcXcRqwPxjxRmGHtC+wWohKHtCHzJmE=
+github.com/Gre-Z/common v0.0.0-20191024025434-2dbc6bd196f9/go.mod h1:b5J9o16Ec1LAwq6QVv+pNECF3sxcin2dMKprGZX43mA=
+github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
+github.com/aliyun/alibaba-cloud-sdk-go v1.61.623 h1:iKyKSF67tLwsVSs6okuvVdr9C9kV7y4OGNTCx16IKfg=
+github.com/aliyun/alibaba-cloud-sdk-go v1.61.623/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA=
+github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM=
+github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
+github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
+github.com/garyburd/redigo v1.6.2 h1:yE/pwKCrbLpLpQICzYTeZ7JsTA/C53wFTJHaEtRqniM=
+github.com/garyburd/redigo v1.6.2/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
+github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
+github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
+github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
+github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
+github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
+github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
+github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
+github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
+github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
+github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
+github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
+github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
+github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
+github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
+github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
+github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
+github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o=
+github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=
+github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
+github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
+github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M=
+github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
+github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
+github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
+github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
+github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
+github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
+github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-sqlite3 v1.14.0 h1:mLyGNKR8+Vv9CAU7PphKa2hkEqxxhn8i32J6FPj1/QA=
+github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
+github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
+github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
+github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs=
+github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
+github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
+github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
+github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd h1:GGJVjV8waZKRHrgwvtH66z9ZGVurTD1MT0n1Bb+q4aM=
+golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk=
+gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/model/Apiform/Api.go b/model/Apiform/Api.go
new file mode 100644
index 0000000..f38da6c
--- /dev/null
+++ b/model/Apiform/Api.go
@@ -0,0 +1,117 @@
+package Apiform
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "github.com/garyburd/redigo/redis"
+ "github.com/satori/go.uuid"
+ "log"
+ "ssh_manage/common"
+ "ssh_manage/database"
+ "ssh_manage/model"
+)
+
+type Login struct {
+ Phone int `form:"phone" binding:"required"`
+ Code string `form:"code" binding:"required"`
+}
+
+type Send struct {
+ Phone string `form:"phone" binding:"required"`
+}
+
+type Slist struct {
+ Page int `form:"page" binding:"required"`
+ Limit int `form:"limit" binding:"required"`
+}
+
+type List_resp struct {
+ List []model.Server
+ Count uint
+}
+
+type GetTerm struct {
+ ID uint `form:"id" binding:"required"`
+ Password string `form:"setpass" binding:"required"`
+}
+
+type WsAuth struct {
+ Sid string `uri:"sid" binding:"required,uuid"`
+}
+
+type Edit struct {
+ ID uint `form:"id" binding:"required"`
+ Nickname string `form:"nickname"`
+ Ip string `form:"ip"`
+ Port int `form:"port"`
+ Username string `form:"username"`
+}
+
+type EditPass struct {
+ ID uint `form:"id" binding:"required"`
+ Password string `form:"password" binding:"required"`
+}
+
+type Addser struct {
+ Nickname string `form:"nickname"`
+ Ip string `form:"ip" binding:"required"`
+ Port int `form:"port" binding:"required"`
+ Username string `form:"username" binding:"required"`
+ Password string `form:"password" binding:"required"`
+}
+
+type SerInfo struct {
+ ID uint
+ Ip string
+ Port int
+ Username string
+ Password string
+ BindUser uint
+}
+
+func (s *Send) SendCaptcha(ip string) (err error) {
+ cache := database.Cache.Get()
+ defer cache.Close()
+ ipexists, _ := redis.Bool(cache.Do("EXISTS", ip))
+ phoneexists, _ := redis.Bool(cache.Do("EXISTS", s.Phone+"_time"))
+ if ipexists || phoneexists {
+ err = errors.New("请勿频繁发送验证码")
+ return
+ }
+ cache.Send("MULTI") //开启事务操作
+ cache.Send("SETEX", s.Phone+"_time", 60*2, nil) //记录手机号与IP,防止重复发送
+ cache.Send("SETEX", ip, 60*2, nil)
+ capcha, err := common.Sendsms(s.Phone)
+ if err != nil {
+ cache.Do("DISCARD") //发送失败则取消事务
+ log.Println(err.Error())
+ return
+ }
+ cache.Send("SETEX", s.Phone, 60*5, capcha) //延长过期时间,用于校验
+ cache.Do("EXEC") //提交事务
+ return
+}
+
+func (l *Login) Verify() (key, code string) {
+ return fmt.Sprintf("%d", l.Phone), l.Code
+}
+
+func (t *GetTerm) Decode(server model.Server) (sid string, err error) {
+ sid = uuid.Must(uuid.NewV4(), nil).String()
+ //log.Println(server)
+ s_pass := common.AesDecryptCBC(server.Password, []byte(t.Password))
+ if s_pass == "" {
+ return "", errors.New("秘钥验证失败")
+ } else {
+ var serinfo = SerInfo{server.ID,server.Ip,server.Port,server.Username,s_pass,server.BindUser}
+ //server.Password = s_pass //用于建立连接
+ cache := database.Cache.Get()
+ defer cache.Close()
+ s_info, _ := json.Marshal(serinfo)
+ //log.Println(string(s_info))
+ cache.Do("SETEX", sid, 10, s_info) //缓存10s,用于建立连接和验证权限
+ //log.Println(sid)
+ }
+ return sid, nil
+}
diff --git a/model/Apiform/Response.go b/model/Apiform/Response.go
new file mode 100644
index 0000000..ac561c0
--- /dev/null
+++ b/model/Apiform/Response.go
@@ -0,0 +1,8 @@
+package Apiform
+
+type Resp struct {
+ Code int `json:"code"`
+ Data interface{} `json:"data"`
+ Msg string `json:"msg"`
+ Token string `json:"token"`
+}
\ No newline at end of file
diff --git a/model/Model.go b/model/Model.go
new file mode 100644
index 0000000..16d97bf
--- /dev/null
+++ b/model/Model.go
@@ -0,0 +1,12 @@
+package model
+
+import (
+ "github.com/Gre-Z/common/jtime"
+)
+
+type Model struct {
+ ID uint `gorm:"primary_key"`
+ CreatedAt jtime.JsonTime
+ UpdatedAt jtime.JsonTime
+ DeletedAt jtime.JsonTime `sql:"index"`
+}
diff --git a/model/Server.go b/model/Server.go
new file mode 100644
index 0000000..e0a4473
--- /dev/null
+++ b/model/Server.go
@@ -0,0 +1,16 @@
+package model
+
+import (
+ "github.com/Gre-Z/common/jtime"
+)
+
+type Server struct {
+ Model
+ Nickname string
+ Ip string `grom:"size:15"`
+ Port int
+ Username string `grom:"size:255"`
+ Password string `gorm:"type:longtext" json:"-"` //存放加密后的登录密码,解密密码存放到用户浏览器
+ BindUser uint `json:"-"`
+ BeforeTime jtime.JsonTime
+}
diff --git a/model/User.go b/model/User.go
new file mode 100644
index 0000000..a3af909
--- /dev/null
+++ b/model/User.go
@@ -0,0 +1,8 @@
+package model
+
+type User struct {
+ Model
+ Phone int `gorm:"not null;unique;type:bigint"`
+ Email string `gorm:"unique"`
+ Servers []Server `gorm:"ForeignKey:BindUser"`
+}
diff --git a/serve.go b/serve.go
new file mode 100644
index 0000000..eeb6fc3
--- /dev/null
+++ b/serve.go
@@ -0,0 +1,68 @@
+package main
+
+import (
+ "github.com/gin-gonic/gin"
+ "log"
+ "net/http"
+ "ssh_manage/config"
+ _ "ssh_manage/config"
+ "ssh_manage/controller"
+ "ssh_manage/controller/middleware"
+ _ "ssh_manage/database" //初始化Mysql/Redis连接池
+)
+
+var run_mode = config.Config.Web.Model
+var web_port = config.Config.Web.Port
+
+func init() {
+ log.SetFlags(log.LstdFlags | log.Lshortfile)
+}
+
+func main() {
+ gin.SetMode(run_mode)
+ gin.DisableConsoleColor()
+ router := gin.Default()
+ router.Use(gin.Recovery())
+ router.LoadHTMLGlob("view/*")
+ router.Static("/static", "./static")
+ router.GET("/", func(c *gin.Context) {
+ c.Redirect(302, "/login")
+ })
+ router.GET("/login", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "index.html", nil)
+ })
+ router.GET("/console", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "console.html", nil)
+ })
+ router.GET("/servers", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "s_list.html", nil)
+ })
+ router.GET("/add", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "add.html", nil)
+ })
+ router.GET("/setpass", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "reset.html", nil)
+ })
+ router.GET("/openterm", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "open_term.html", nil)
+ })
+ router.GET("/term", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "term.html", nil)
+ })
+
+ api := router.Group("/v1")
+ {
+ api.POST("/login", controller.Login)
+ api.POST("/send", controller.Send)
+ api.GET("/term/:sid", controller.WsSsh)
+ api.Use(middleware.Auth()).GET("/userinfo", controller.Info)
+ api.Use(middleware.Auth()).POST("/nickname", controller.UpdataNick)
+ api.Use(middleware.Auth()).POST("/addser", controller.Addser)
+ api.Use(middleware.Auth()).POST("/repass", controller.Resetpass)
+ api.Use(middleware.Auth()).POST("/delete", controller.Del)
+ api.Use(middleware.Auth()).POST("/getterm", controller.GetTerm)
+ }
+ if err := router.Run(web_port); err != nil {
+ log.Panicf("Web Serve Start Err : %s", err.Error())
+ }
+}
diff --git a/static/assets/css/admin.css b/static/assets/css/admin.css
new file mode 100644
index 0000000..3f2218e
--- /dev/null
+++ b/static/assets/css/admin.css
@@ -0,0 +1,364 @@
+/*
+ * 自定义管理界面,基于LayUI框架构建
+ * Layui link: http://www.layui.com
+ * Custom style author: Bie Jun
+*/
+
+
+/*
+ * 字体图标
+*/
+
+@font-face {font-family: "AI";
+ src: url('../font/ai.eot?t=1522660080732'); /* IE9*/
+ src: url('../font/ai.eot?t=1522660080732#iefix') format('embedded-opentype'), /* IE6-IE8 */
+ url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAY8AAsAAAAACOwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFZW7klTY21hcAAAAYAAAABxAAABsgVg1KRnbHlmAAAB9AAAAikAAALAJwyXdWhlYWQAAAQgAAAALwAAADYQ72wdaGhlYQAABFAAAAAcAAAAJAfeA4ZobXR4AAAEbAAAABMAAAAUE+kAAGxvY2EAAASAAAAADAAAAAwBgAIWbWF4cAAABIwAAAAeAAAAIAEUAF1uYW1lAAAErAAAAUgAAAIlgV2vXHBvc3QAAAX0AAAARgAAAFxjcyq+eJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2Bk/s04gYGVgYOpk+kMAwNDP4RmfM1gxMjBwMDEwMrMgBUEpLmmMDgwVDxPY27438AQw9zA0AAUZgTJAQAr+wzWeJzFkcENgCAQBOdAjTGW4tu31fjy5YvyrAbL0IXzoRW4lyF7myMQAFogikk0YDtG0abUah4Zat6wqB/oCaqU53yc63Upe3uXac6r+Ki9QabjN9l/R3811nV5Or046UFXzLNTfiQfTpk5V4dwAxJQGNAAAAB4nFWQP2/TQBjG773L2YkvsVP/TZzYiWMSg0qNSN0EBCQMLEUMIBY6EOgHgIGlqsSQpRUDA0tGGBASc6cuHYpUqUjN0m8AhYlOHWByXM4ulYr1+rnn3nul+92DKEKn38kOqSANXUbX0T30ECEQ5qElYwe8IArxPBgeNSxdJoEfeKLfCskdsFqCbnZ7UccSREEBGVxY9Lq9IMQBLEUDfAu6pgNQrdmP1XZdJe9AqgTuRnIffwSj4deVwUKyfHWod5tafq2oqlVVfZsXKM1jnFNkeGGZBVqQhOQTVWxjp3EFN6BYDewHK6VmTV19E7102lYBYDwGrdaUPw/n7Dler21TU6tiuZSv2CX/kg5rP1lFKzqdH4h/hL91l+ySMWLIQs30nUg0kdVD/Q4iIQQD6LtgyUAsz/BEqx/At2lyQiko0ykolCYn063jXO54K9MPk+QGfJ0sHB2RcXp0YTTeOB/iih9N7qZTKMfvPyVfOEZ6v48ihDQvzdD30jRppotZh1zw7TTna9AfQAgKCLq1Sm4rhqHEe1zJ8uwg3eAlrqV4P/XkJteZxRxDej5iYLjSepHhbcM1eP0+W5LNs/VQ4sejJ8w1QHrFXJbmlMvC+o8TvBCiHucxdYFmKmYd7YJvC61ONIQghAE0wNRF8j7eK+t6OcONtzNEZXbAW3KGqMT73ONfzDHZs6cc1GHrjIOC3tB5/eE/pD7ZPHeHkllnoxXJMf/R/gVcdIfdAAAAeJxjYGRgYADisxEb+eL5bb4ycLMwgMC1F8IfEPT/AywMzA1ALgcDE0gUAEFcC2cAeJxjYGRgYG7438AQw8IAAkCSkQEVsAIARwsCbnicY2FgYGB+ycDAwoDAAA6bAP0AAAAAAAB2ALYBCgFgeJxjYGRgYGBlCARiEGACYi4gZGD4D+YzAAARLQFyAAB4nF2RPU7DQBCFn0MShCNRgIAOLRQUIOwkZTorUiK3KVLQJc46P7K91mYTKSeh4AQUFJyCgjtwFl6cCQW2dvTNmzczKxvABX7g4fBc8RzYQ43ZgWs4xY3wCbNb4TpZCTfQwr1wk/qzsI8nhMItXOKFE7z6GbNH5MIeJ70K13CON+ET6u/Cdb4fwg1c41O4Sf1L2McY38ItPHh3ft/qidMzNd2pZWKK1BTOj+KRnm+yiY3iKB5ru16aQnWCdhQPdaHt0b/ezrvOpSq1JlcDNuosM6q0ZqUTFyycK3thmIoeJCbn+j4sNCZwjDN+mil2jEskMCiQVtHRFyHGiJ45Nsjot5WyP2OqFmv27L0KHQRoV5UhK0VV/T9/jS0ndak67lA8lt05aSAbNbdkZIWyqq2oJNQDLKquEj3+pPDvhkd/UN08/wU7iFeyeJxjYGKAAC4G7ICVkYmRmZGFkZWRjYGxQiyxqCi/XLcoMz2jRDc5syg5J1W3WDefIzc1rzQtPyeFC8QozQMxGRgAmgAQtAAA') format('woff'),
+ url('../font/ai.ttf?t=1522660080732') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
+ url('../font/ai.svg?t=1522660080732#AI') format('svg'); /* iOS 4.1- */
+}
+
+.ai {
+ font-family:"AI" !important;
+ font-size:16px;
+ font-style:normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.ai-enter:before { content: "\e766"; }
+.ai-menufold:before { content: "\e636"; }
+.ai-menuunfold:before { content: "\e6c0"; }
+
+
+/* 预定义整体布局配色,你可以修改这里的色值为自己喜欢的颜色 */
+
+.layui-layout-body{
+ background-color: #f0f2f5;
+}
+
+.layui-layout-admin .layui-header{
+ background-color: #fff;
+}
+
+.layui-layout-admin .layui-side,
+.layui-nav,
+.custom-admin .layui-nav-tree .layui-nav-item.layui-nav-itemed > a,
+.layui-nav-tree .layui-nav-item a:hover{
+ background-color: #001529;
+}
+
+.custom-admin .layui-nav-child,
+.custom-admin .layui-nav-child a{
+ background-color: #000c17!important;
+}
+.custom-admin .layui-nav-child dd.layui-this a{
+ background-color: #177ce3;
+ background-repeat: repeat-y;
+ background-image: -moz-linear-gradient(left,#29adeb,#177ce3);
+ background-image: -webkit-linear-gradient(left,#29adeb,#177ce3);
+ background-image: -o-linear-gradient(left,#29adeb,#177ce3);
+ background-image: linear-gradient(left,#29adeb,#177ce3);
+}
+
+.custom-header .layui-nav,
+.custom-header .layui-nav .layui-nav-item a{
+ color: rgba(0,0,0,.8);
+}
+.custom-admin .layui-nav-tree .layui-nav-item a{
+ color: hsla(0,0%,100%,.65);
+ transition: all .3s;
+}
+
+.custom-admin .layui-nav-tree .layui-nav-item a:hover,
+.custom-admin .layui-nav-tree .layui-nav-item a:hover .layui-nav-more:before,
+.custom-admin .layui-nav-tree .layui-nav-itemed > a .layui-nav-more:before{
+ color: #fff;
+}
+
+.custom-admin .layui-nav-tree .layui-nav-item a > i{
+ margin-right: 5px;
+}
+
+.custom-admin .layui-nav-tree .layui-nav-item a > em{
+ font-style: normal;
+}
+
+.layui-layout-admin .layui-footer{
+ background-color: #e8eaed;
+}
+
+/* 折叠边栏 */
+
+.layui-layout.fold-side-bar .layui-side.custom-admin,
+.layui-layout.fold-side-bar .layui-side.custom-admin .layui-nav-tree{
+ width: 60px;
+}
+
+.layui-layout.fold-side-bar .layui-side.custom-admin .layui-side-scroll{
+ width: 80px;
+}
+
+.layui-layout.fold-side-bar .custom-header .layui-nav.layui-layout-left,
+.layui-layout.fold-side-bar .layui-body,
+.layui-layout.fold-side-bar .layui-footer{
+ left: 60px;
+}
+
+.fold-side-bar .custom-admin .custom-logo img{
+ margin-left: 12px;
+}
+
+.fold-side-bar .layui-side.custom-admin .layui-nav-more,
+.fold-side-bar .custom-admin .layui-nav-item a > em,
+.fold-side-bar .custom-admin .custom-logo h1,
+.fold-side-bar .layui-side.custom-admin .layui-nav-child{
+ display: none;
+}
+
+/* 布局样式重定义 */
+
+html, body , .app-container{
+ height: 100%;
+}
+
+.layui-layout{
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ overflow: hidden;
+}
+
+.app-container{
+ position: absolute;
+ top: 0;
+ left:0;
+ right: 0;
+ bottom: 0;
+ margin:0;
+}
+
+.app-container .layui-tab-content{
+ position: absolute;
+ top: 40px;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ padding: 0;
+ overflow: hidden;
+}
+
+.app-container .layui-tab-content .layui-tab-item,
+.app-container .layui-tab-item > iframe{
+ width: 100%;
+ height: 100%;
+}
+.custom-header{
+ height: 50px;
+}
+
+.custom-tab{
+ padding: 0 20px;
+ background-color: #fff;
+ box-shadow: rgba(0, 21, 41, 0.08) 0px 1px 4px;
+ border:none;
+ border-top:1px solid #f6f6f6;
+ z-index: 999;
+}
+
+.layui-tab-title.custom-tab .layui-this{
+ background-color: #f0f4fb;
+}
+
+.layui-tab-title.custom-tab .layui-this:after{
+ border: none;
+ height: 3px;
+ background-color: #177ce3;
+ background-repeat: repeat-y;
+ background-image: -moz-linear-gradient(left,#29adeb,#177ce3);
+ background-image: -webkit-linear-gradient(left,#29adeb,#177ce3);
+ background-image: -o-linear-gradient(left,#29adeb,#177ce3);
+ background-image: linear-gradient(left,#29adeb,#177ce3);
+}
+
+.layui-layout-admin .layui-side.custom-admin,
+.layui-layout-admin .layui-side.custom-admin .layui-nav-tree{
+ width: 260px;
+}
+
+.layui-layout-admin .layui-side.custom-admin .layui-side-scroll{
+ width: 280px;
+}
+
+.layui-body,
+.layui-layout-admin .layui-footer,
+.layui-layout-admin .custom-header .layui-nav.layui-layout-left{
+ left: 260px;
+}
+
+.layui-layout-admin .layui-side.custom-admin{
+ top: 0;
+ z-index: 1001;
+ -webkit-box-shadow: 2px 0 6px rgba(0,21,41,.35);
+ box-shadow: 2px 0 6px rgba(0,21,41,.35);
+}
+
+.custom-header .layui-nav .layui-nav-item{
+ line-height: 50px;
+}
+
+.custom-header .layui-nav-child{
+ top: 55px;
+}
+
+.custom-admin .layui-nav-itemed .layui-nav-child dd a{
+ padding-left: 43px;
+}
+
+.layui-layout-admin .layui-body{
+ top: 50px;
+}
+
+.layui-layout-admin .layui-footer{
+ border-top: 1px solid #dfdfdf;
+}
+.layui-layout-admin .layui-footer p{
+ color: rgba(0,0,0,.45);
+}
+
+.layui-side.custom-admin,
+.layui-body,
+.custom-header,
+.custom-header .layui-nav.layui-layout-left,
+.layui-footer{
+ transition: all .3s;
+ -webkit-transition: all .3s;
+}
+
+@media screen and (max-width: 992px){
+ .layui-layout-admin .layui-side.custom-admin {
+ transform: translate3d(-265px,0,0);
+ -webkit-transform: translate3d(-265px,0,0);
+ }
+
+ .layui-body,
+ .layui-layout-admin .layui-footer,
+ .layui-layout-admin .custom-header .layui-nav.layui-layout-left{
+ left: 0;
+ }
+
+ .fold-side-bar-xs .layui-side.custom-admin{
+ -webkit-transform: translate(0,0,0);
+ transform: translate3d(0,0,0);
+ }
+
+ .fold-side-bar-xs .layui-body,
+ .fold-side-bar-xs .layui-footer,
+ .fold-side-bar-xs .custom-header{
+ transform: translate3d(260px,0,0);
+ -webkit-transform: translate3d(260px,0,0);
+ }
+}
+
+
+.custom-header .layui-nav .layui-nav-more,
+.custom-admin .layui-nav .layui-nav-more{
+ width: 25px;
+ top: 0;
+ border:none;
+ overflow: visible;
+ margin-top: 0;
+}
+
+.custom-header .layui-nav .layui-nav-more{
+ top: 0;
+ right: -10px;
+}
+
+.custom-header .layui-nav .slide-sidebar a.icon-font{
+ padding: 0;
+ color: #2c2e2f;
+}
+
+.custom-header .layui-nav .slide-sidebar a.icon-font > i{
+ font-size: 18px;
+}
+
+.custom-header .layui-nav .layui-nav-more:before,
+.custom-admin .layui-nav .layui-nav-more:before,
+.custom-admin .layui-nav-itemed .layui-nav-more:before{
+ font-family: layui-icon!important;
+ font-size: 11px;
+ color: #6d747a;
+}
+
+.custom-header .layui-nav .layui-nav-more:before,
+.custom-admin .layui-nav .layui-nav-more:before,
+.custom-admin .layui-nav-itemed .layui-nav-more:before{
+ position: absolute;
+ left: 0;
+ top: 0;
+}
+
+.custom-header .layui-nav .layui-nav-more:before,
+.custom-admin .layui-nav .layui-nav-more:before{
+ content: '\e61a';
+}
+
+.custom-admin .layui-nav-itemed > a .layui-nav-more:before{
+ content: '\e619';
+}
+
+.custom-logo{
+ height: 50px;
+ line-height: 50px;
+ color: #fff;
+ background-color: #002140;
+ vertical-align: middle;
+}
+.custom-logo img{
+ margin-left: 20px;
+ height: 32px;
+}
+
+.custom-logo h1{
+ display: inline;
+ margin: 0 20px 0 10px;
+ font-size: 18px;
+ vertical-align: middle;
+}
+
+.layui-nav-bar{
+ height: 3px;
+ background-color: #177ce3;
+ background-repeat: repeat-y;
+ background-image: -moz-linear-gradient(left,#29adeb,#177ce3);
+ background-image: -webkit-linear-gradient(left,#29adeb,#177ce3);
+ background-image: -o-linear-gradient(left,#29adeb,#177ce3);
+ background-image: linear-gradient(left,#29adeb,#177ce3);
+}
+
+.custom-header .layui-nav-bar{
+ top: 0!important;
+}
+.layui-nav-tree .layui-nav-bar{
+ display: none;
+}
+
+.custom-header .layui-tab-title li
+
+.custom-header .layui-tab-title li.layui-this .layui-tab-close{
+ color: #000;
+}
+
+.mobile-mask{
+ position: fixed;
+ display: none;
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ background-color: rgba(0,0,0,.3);
+ z-index: 1000;
+}
\ No newline at end of file
diff --git a/static/assets/css/layui.css b/static/assets/css/layui.css
new file mode 100644
index 0000000..5a10469
--- /dev/null
+++ b/static/assets/css/layui.css
@@ -0,0 +1,2 @@
+/** layui-v2.5.6 MIT License By https://www.layui.com */
+ .layui-inline,img{display:inline-block;vertical-align:middle}h1,h2,h3,h4,h5,h6{font-weight:400}.layui-edge,.layui-header,.layui-inline,.layui-main{position:relative}.layui-body,.layui-edge,.layui-elip{overflow:hidden}.layui-btn,.layui-edge,.layui-inline,img{vertical-align:middle}.layui-btn,.layui-disabled,.layui-icon,.layui-unselect{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.layui-elip,.layui-form-checkbox span,.layui-form-pane .layui-form-label{text-overflow:ellipsis;white-space:nowrap}.layui-breadcrumb,.layui-tree-btnGroup{visibility:hidden}blockquote,body,button,dd,div,dl,dt,form,h1,h2,h3,h4,h5,h6,input,li,ol,p,pre,td,textarea,th,ul{margin:0;padding:0;-webkit-tap-highlight-color:rgba(0,0,0,0)}a:active,a:hover{outline:0}img{border:none}li{list-style:none}table{border-collapse:collapse;border-spacing:0}h4,h5,h6{font-size:100%}button,input,optgroup,option,select,textarea{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;outline:0}pre{white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word}body{line-height:24px;font:14px Helvetica Neue,Helvetica,PingFang SC,Tahoma,Arial,sans-serif}hr{height:1px;margin:10px 0;border:0;clear:both}a{color:#333;text-decoration:none}a:hover{color:#777}a cite{font-style:normal;*cursor:pointer}.layui-border-box,.layui-border-box *{box-sizing:border-box}.layui-box,.layui-box *{box-sizing:content-box}.layui-clear{clear:both;*zoom:1}.layui-clear:after{content:'\20';clear:both;*zoom:1;display:block;height:0}.layui-inline{*display:inline;*zoom:1}.layui-edge{display:inline-block;width:0;height:0;border-width:6px;border-style:dashed;border-color:transparent}.layui-edge-top{top:-4px;border-bottom-color:#999;border-bottom-style:solid}.layui-edge-right{border-left-color:#999;border-left-style:solid}.layui-edge-bottom{top:2px;border-top-color:#999;border-top-style:solid}.layui-edge-left{border-right-color:#999;border-right-style:solid}.layui-disabled,.layui-disabled:hover{color:#d2d2d2!important;cursor:not-allowed!important}.layui-circle{border-radius:100%}.layui-show{display:block!important}.layui-hide{display:none!important}@font-face{font-family:layui-icon;src:url(../font/iconfont.eot?v=256);src:url(../font/iconfont.eot?v=256#iefix) format('embedded-opentype'),url(../font/iconfont.woff2?v=256) format('woff2'),url(../font/iconfont.woff?v=256) format('woff'),url(../font/iconfont.ttf?v=256) format('truetype'),url(../font/iconfont.svg?v=256#layui-icon) format('svg')}.layui-icon{font-family:layui-icon!important;font-size:16px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.layui-icon-reply-fill:before{content:"\e611"}.layui-icon-set-fill:before{content:"\e614"}.layui-icon-menu-fill:before{content:"\e60f"}.layui-icon-search:before{content:"\e615"}.layui-icon-share:before{content:"\e641"}.layui-icon-set-sm:before{content:"\e620"}.layui-icon-engine:before{content:"\e628"}.layui-icon-close:before{content:"\1006"}.layui-icon-close-fill:before{content:"\1007"}.layui-icon-chart-screen:before{content:"\e629"}.layui-icon-star:before{content:"\e600"}.layui-icon-circle-dot:before{content:"\e617"}.layui-icon-chat:before{content:"\e606"}.layui-icon-release:before{content:"\e609"}.layui-icon-list:before{content:"\e60a"}.layui-icon-chart:before{content:"\e62c"}.layui-icon-ok-circle:before{content:"\1005"}.layui-icon-layim-theme:before{content:"\e61b"}.layui-icon-table:before{content:"\e62d"}.layui-icon-right:before{content:"\e602"}.layui-icon-left:before{content:"\e603"}.layui-icon-cart-simple:before{content:"\e698"}.layui-icon-face-cry:before{content:"\e69c"}.layui-icon-face-smile:before{content:"\e6af"}.layui-icon-survey:before{content:"\e6b2"}.layui-icon-tree:before{content:"\e62e"}.layui-icon-ie:before{content:"\e7bb"}.layui-icon-upload-circle:before{content:"\e62f"}.layui-icon-add-circle:before{content:"\e61f"}.layui-icon-download-circle:before{content:"\e601"}.layui-icon-templeate-1:before{content:"\e630"}.layui-icon-util:before{content:"\e631"}.layui-icon-face-surprised:before{content:"\e664"}.layui-icon-edit:before{content:"\e642"}.layui-icon-speaker:before{content:"\e645"}.layui-icon-down:before{content:"\e61a"}.layui-icon-file:before{content:"\e621"}.layui-icon-layouts:before{content:"\e632"}.layui-icon-rate-half:before{content:"\e6c9"}.layui-icon-add-circle-fine:before{content:"\e608"}.layui-icon-prev-circle:before{content:"\e633"}.layui-icon-read:before{content:"\e705"}.layui-icon-404:before{content:"\e61c"}.layui-icon-carousel:before{content:"\e634"}.layui-icon-help:before{content:"\e607"}.layui-icon-code-circle:before{content:"\e635"}.layui-icon-windows:before{content:"\e67f"}.layui-icon-water:before{content:"\e636"}.layui-icon-username:before{content:"\e66f"}.layui-icon-find-fill:before{content:"\e670"}.layui-icon-about:before{content:"\e60b"}.layui-icon-location:before{content:"\e715"}.layui-icon-up:before{content:"\e619"}.layui-icon-pause:before{content:"\e651"}.layui-icon-date:before{content:"\e637"}.layui-icon-layim-uploadfile:before{content:"\e61d"}.layui-icon-delete:before{content:"\e640"}.layui-icon-play:before{content:"\e652"}.layui-icon-top:before{content:"\e604"}.layui-icon-firefox:before{content:"\e686"}.layui-icon-friends:before{content:"\e612"}.layui-icon-refresh-3:before{content:"\e9aa"}.layui-icon-ok:before{content:"\e605"}.layui-icon-layer:before{content:"\e638"}.layui-icon-face-smile-fine:before{content:"\e60c"}.layui-icon-dollar:before{content:"\e659"}.layui-icon-group:before{content:"\e613"}.layui-icon-layim-download:before{content:"\e61e"}.layui-icon-picture-fine:before{content:"\e60d"}.layui-icon-link:before{content:"\e64c"}.layui-icon-diamond:before{content:"\e735"}.layui-icon-log:before{content:"\e60e"}.layui-icon-key:before{content:"\e683"}.layui-icon-rate-solid:before{content:"\e67a"}.layui-icon-fonts-del:before{content:"\e64f"}.layui-icon-unlink:before{content:"\e64d"}.layui-icon-fonts-clear:before{content:"\e639"}.layui-icon-triangle-r:before{content:"\e623"}.layui-icon-circle:before{content:"\e63f"}.layui-icon-radio:before{content:"\e643"}.layui-icon-align-center:before{content:"\e647"}.layui-icon-align-right:before{content:"\e648"}.layui-icon-align-left:before{content:"\e649"}.layui-icon-loading-1:before{content:"\e63e"}.layui-icon-return:before{content:"\e65c"}.layui-icon-fonts-strong:before{content:"\e62b"}.layui-icon-upload:before{content:"\e67c"}.layui-icon-dialogue:before{content:"\e63a"}.layui-icon-video:before{content:"\e6ed"}.layui-icon-headset:before{content:"\e6fc"}.layui-icon-cellphone-fine:before{content:"\e63b"}.layui-icon-add-1:before{content:"\e654"}.layui-icon-face-smile-b:before{content:"\e650"}.layui-icon-fonts-html:before{content:"\e64b"}.layui-icon-screen-full:before{content:"\e622"}.layui-icon-form:before{content:"\e63c"}.layui-icon-cart:before{content:"\e657"}.layui-icon-camera-fill:before{content:"\e65d"}.layui-icon-tabs:before{content:"\e62a"}.layui-icon-heart-fill:before{content:"\e68f"}.layui-icon-fonts-code:before{content:"\e64e"}.layui-icon-ios:before{content:"\e680"}.layui-icon-at:before{content:"\e687"}.layui-icon-fire:before{content:"\e756"}.layui-icon-set:before{content:"\e716"}.layui-icon-fonts-u:before{content:"\e646"}.layui-icon-triangle-d:before{content:"\e625"}.layui-icon-tips:before{content:"\e702"}.layui-icon-picture:before{content:"\e64a"}.layui-icon-more-vertical:before{content:"\e671"}.layui-icon-bluetooth:before{content:"\e689"}.layui-icon-flag:before{content:"\e66c"}.layui-icon-loading:before{content:"\e63d"}.layui-icon-fonts-i:before{content:"\e644"}.layui-icon-refresh-1:before{content:"\e666"}.layui-icon-rmb:before{content:"\e65e"}.layui-icon-addition:before{content:"\e624"}.layui-icon-home:before{content:"\e68e"}.layui-icon-time:before{content:"\e68d"}.layui-icon-user:before{content:"\e770"}.layui-icon-notice:before{content:"\e667"}.layui-icon-chrome:before{content:"\e68a"}.layui-icon-edge:before{content:"\e68b"}.layui-icon-login-weibo:before{content:"\e675"}.layui-icon-voice:before{content:"\e688"}.layui-icon-upload-drag:before{content:"\e681"}.layui-icon-login-qq:before{content:"\e676"}.layui-icon-snowflake:before{content:"\e6b1"}.layui-icon-heart:before{content:"\e68c"}.layui-icon-logout:before{content:"\e682"}.layui-icon-file-b:before{content:"\e655"}.layui-icon-template:before{content:"\e663"}.layui-icon-transfer:before{content:"\e691"}.layui-icon-auz:before{content:"\e672"}.layui-icon-console:before{content:"\e665"}.layui-icon-app:before{content:"\e653"}.layui-icon-prev:before{content:"\e65a"}.layui-icon-website:before{content:"\e7ae"}.layui-icon-next:before{content:"\e65b"}.layui-icon-component:before{content:"\e857"}.layui-icon-android:before{content:"\e684"}.layui-icon-more:before{content:"\e65f"}.layui-icon-login-wechat:before{content:"\e677"}.layui-icon-shrink-right:before{content:"\e668"}.layui-icon-spread-left:before{content:"\e66b"}.layui-icon-camera:before{content:"\e660"}.layui-icon-note:before{content:"\e66e"}.layui-icon-refresh:before{content:"\e669"}.layui-icon-female:before{content:"\e661"}.layui-icon-male:before{content:"\e662"}.layui-icon-screen-restore:before{content:"\e758"}.layui-icon-password:before{content:"\e673"}.layui-icon-senior:before{content:"\e674"}.layui-icon-theme:before{content:"\e66a"}.layui-icon-tread:before{content:"\e6c5"}.layui-icon-praise:before{content:"\e6c6"}.layui-icon-star-fill:before{content:"\e658"}.layui-icon-rate:before{content:"\e67b"}.layui-icon-template-1:before{content:"\e656"}.layui-icon-vercode:before{content:"\e679"}.layui-icon-service:before{content:"\e626"}.layui-icon-cellphone:before{content:"\e678"}.layui-icon-print:before{content:"\e66d"}.layui-icon-cols:before{content:"\e610"}.layui-icon-wifi:before{content:"\e7e0"}.layui-icon-export:before{content:"\e67d"}.layui-icon-rss:before{content:"\e808"}.layui-icon-slider:before{content:"\e714"}.layui-icon-email:before{content:"\e618"}.layui-icon-subtraction:before{content:"\e67e"}.layui-icon-mike:before{content:"\e6dc"}.layui-icon-light:before{content:"\e748"}.layui-icon-gift:before{content:"\e627"}.layui-icon-mute:before{content:"\e685"}.layui-icon-reduce-circle:before{content:"\e616"}.layui-icon-music:before{content:"\e690"}.layui-main{width:1140px;margin:0 auto}.layui-header{z-index:1000;height:60px}.layui-header a:hover{transition:all .5s;-webkit-transition:all .5s}.layui-side{position:fixed;left:0;top:0;bottom:0;z-index:999;width:200px;overflow-x:hidden}.layui-side-scroll{position:relative;width:220px;height:100%;overflow-x:hidden}.layui-body{position:absolute;left:200px;right:0;top:0;bottom:0;z-index:998;width:auto;overflow-y:auto;box-sizing:border-box}.layui-layout-body{overflow:hidden}.layui-layout-admin .layui-header{background-color:#23262E}.layui-layout-admin .layui-side{top:60px;width:200px;overflow-x:hidden}.layui-layout-admin .layui-body{position:fixed;top:60px;bottom:44px}.layui-layout-admin .layui-main{width:auto;margin:0 15px}.layui-layout-admin .layui-footer{position:fixed;left:200px;right:0;bottom:0;height:44px;line-height:44px;padding:0 15px;background-color:#eee}.layui-layout-admin .layui-logo{position:absolute;left:0;top:0;width:200px;height:100%;line-height:60px;text-align:center;color:#009688;font-size:16px}.layui-layout-admin .layui-header .layui-nav{background:0 0}.layui-layout-left{position:absolute!important;left:200px;top:0}.layui-layout-right{position:absolute!important;right:0;top:0}.layui-container{position:relative;margin:0 auto;padding:0 15px;box-sizing:border-box}.layui-fluid{position:relative;margin:0 auto;padding:0 15px}.layui-row:after,.layui-row:before{content:'';display:block;clear:both}.layui-col-lg1,.layui-col-lg10,.layui-col-lg11,.layui-col-lg12,.layui-col-lg2,.layui-col-lg3,.layui-col-lg4,.layui-col-lg5,.layui-col-lg6,.layui-col-lg7,.layui-col-lg8,.layui-col-lg9,.layui-col-md1,.layui-col-md10,.layui-col-md11,.layui-col-md12,.layui-col-md2,.layui-col-md3,.layui-col-md4,.layui-col-md5,.layui-col-md6,.layui-col-md7,.layui-col-md8,.layui-col-md9,.layui-col-sm1,.layui-col-sm10,.layui-col-sm11,.layui-col-sm12,.layui-col-sm2,.layui-col-sm3,.layui-col-sm4,.layui-col-sm5,.layui-col-sm6,.layui-col-sm7,.layui-col-sm8,.layui-col-sm9,.layui-col-xs1,.layui-col-xs10,.layui-col-xs11,.layui-col-xs12,.layui-col-xs2,.layui-col-xs3,.layui-col-xs4,.layui-col-xs5,.layui-col-xs6,.layui-col-xs7,.layui-col-xs8,.layui-col-xs9{position:relative;display:block;box-sizing:border-box}.layui-col-xs1,.layui-col-xs10,.layui-col-xs11,.layui-col-xs12,.layui-col-xs2,.layui-col-xs3,.layui-col-xs4,.layui-col-xs5,.layui-col-xs6,.layui-col-xs7,.layui-col-xs8,.layui-col-xs9{float:left}.layui-col-xs1{width:8.33333333%}.layui-col-xs2{width:16.66666667%}.layui-col-xs3{width:25%}.layui-col-xs4{width:33.33333333%}.layui-col-xs5{width:41.66666667%}.layui-col-xs6{width:50%}.layui-col-xs7{width:58.33333333%}.layui-col-xs8{width:66.66666667%}.layui-col-xs9{width:75%}.layui-col-xs10{width:83.33333333%}.layui-col-xs11{width:91.66666667%}.layui-col-xs12{width:100%}.layui-col-xs-offset1{margin-left:8.33333333%}.layui-col-xs-offset2{margin-left:16.66666667%}.layui-col-xs-offset3{margin-left:25%}.layui-col-xs-offset4{margin-left:33.33333333%}.layui-col-xs-offset5{margin-left:41.66666667%}.layui-col-xs-offset6{margin-left:50%}.layui-col-xs-offset7{margin-left:58.33333333%}.layui-col-xs-offset8{margin-left:66.66666667%}.layui-col-xs-offset9{margin-left:75%}.layui-col-xs-offset10{margin-left:83.33333333%}.layui-col-xs-offset11{margin-left:91.66666667%}.layui-col-xs-offset12{margin-left:100%}@media screen and (max-width:768px){.layui-hide-xs{display:none!important}.layui-show-xs-block{display:block!important}.layui-show-xs-inline{display:inline!important}.layui-show-xs-inline-block{display:inline-block!important}}@media screen and (min-width:768px){.layui-container{width:750px}.layui-hide-sm{display:none!important}.layui-show-sm-block{display:block!important}.layui-show-sm-inline{display:inline!important}.layui-show-sm-inline-block{display:inline-block!important}.layui-col-sm1,.layui-col-sm10,.layui-col-sm11,.layui-col-sm12,.layui-col-sm2,.layui-col-sm3,.layui-col-sm4,.layui-col-sm5,.layui-col-sm6,.layui-col-sm7,.layui-col-sm8,.layui-col-sm9{float:left}.layui-col-sm1{width:8.33333333%}.layui-col-sm2{width:16.66666667%}.layui-col-sm3{width:25%}.layui-col-sm4{width:33.33333333%}.layui-col-sm5{width:41.66666667%}.layui-col-sm6{width:50%}.layui-col-sm7{width:58.33333333%}.layui-col-sm8{width:66.66666667%}.layui-col-sm9{width:75%}.layui-col-sm10{width:83.33333333%}.layui-col-sm11{width:91.66666667%}.layui-col-sm12{width:100%}.layui-col-sm-offset1{margin-left:8.33333333%}.layui-col-sm-offset2{margin-left:16.66666667%}.layui-col-sm-offset3{margin-left:25%}.layui-col-sm-offset4{margin-left:33.33333333%}.layui-col-sm-offset5{margin-left:41.66666667%}.layui-col-sm-offset6{margin-left:50%}.layui-col-sm-offset7{margin-left:58.33333333%}.layui-col-sm-offset8{margin-left:66.66666667%}.layui-col-sm-offset9{margin-left:75%}.layui-col-sm-offset10{margin-left:83.33333333%}.layui-col-sm-offset11{margin-left:91.66666667%}.layui-col-sm-offset12{margin-left:100%}}@media screen and (min-width:992px){.layui-container{width:970px}.layui-hide-md{display:none!important}.layui-show-md-block{display:block!important}.layui-show-md-inline{display:inline!important}.layui-show-md-inline-block{display:inline-block!important}.layui-col-md1,.layui-col-md10,.layui-col-md11,.layui-col-md12,.layui-col-md2,.layui-col-md3,.layui-col-md4,.layui-col-md5,.layui-col-md6,.layui-col-md7,.layui-col-md8,.layui-col-md9{float:left}.layui-col-md1{width:8.33333333%}.layui-col-md2{width:16.66666667%}.layui-col-md3{width:25%}.layui-col-md4{width:33.33333333%}.layui-col-md5{width:41.66666667%}.layui-col-md6{width:50%}.layui-col-md7{width:58.33333333%}.layui-col-md8{width:66.66666667%}.layui-col-md9{width:75%}.layui-col-md10{width:83.33333333%}.layui-col-md11{width:91.66666667%}.layui-col-md12{width:100%}.layui-col-md-offset1{margin-left:8.33333333%}.layui-col-md-offset2{margin-left:16.66666667%}.layui-col-md-offset3{margin-left:25%}.layui-col-md-offset4{margin-left:33.33333333%}.layui-col-md-offset5{margin-left:41.66666667%}.layui-col-md-offset6{margin-left:50%}.layui-col-md-offset7{margin-left:58.33333333%}.layui-col-md-offset8{margin-left:66.66666667%}.layui-col-md-offset9{margin-left:75%}.layui-col-md-offset10{margin-left:83.33333333%}.layui-col-md-offset11{margin-left:91.66666667%}.layui-col-md-offset12{margin-left:100%}}@media screen and (min-width:1200px){.layui-container{width:1170px}.layui-hide-lg{display:none!important}.layui-show-lg-block{display:block!important}.layui-show-lg-inline{display:inline!important}.layui-show-lg-inline-block{display:inline-block!important}.layui-col-lg1,.layui-col-lg10,.layui-col-lg11,.layui-col-lg12,.layui-col-lg2,.layui-col-lg3,.layui-col-lg4,.layui-col-lg5,.layui-col-lg6,.layui-col-lg7,.layui-col-lg8,.layui-col-lg9{float:left}.layui-col-lg1{width:8.33333333%}.layui-col-lg2{width:16.66666667%}.layui-col-lg3{width:25%}.layui-col-lg4{width:33.33333333%}.layui-col-lg5{width:41.66666667%}.layui-col-lg6{width:50%}.layui-col-lg7{width:58.33333333%}.layui-col-lg8{width:66.66666667%}.layui-col-lg9{width:75%}.layui-col-lg10{width:83.33333333%}.layui-col-lg11{width:91.66666667%}.layui-col-lg12{width:100%}.layui-col-lg-offset1{margin-left:8.33333333%}.layui-col-lg-offset2{margin-left:16.66666667%}.layui-col-lg-offset3{margin-left:25%}.layui-col-lg-offset4{margin-left:33.33333333%}.layui-col-lg-offset5{margin-left:41.66666667%}.layui-col-lg-offset6{margin-left:50%}.layui-col-lg-offset7{margin-left:58.33333333%}.layui-col-lg-offset8{margin-left:66.66666667%}.layui-col-lg-offset9{margin-left:75%}.layui-col-lg-offset10{margin-left:83.33333333%}.layui-col-lg-offset11{margin-left:91.66666667%}.layui-col-lg-offset12{margin-left:100%}}.layui-col-space1{margin:-.5px}.layui-col-space1>*{padding:.5px}.layui-col-space2{margin:-1px}.layui-col-space2>*{padding:1px}.layui-col-space4{margin:-2px}.layui-col-space4>*{padding:2px}.layui-col-space5{margin:-2.5px}.layui-col-space5>*{padding:2.5px}.layui-col-space6{margin:-3px}.layui-col-space6>*{padding:3px}.layui-col-space8{margin:-4px}.layui-col-space8>*{padding:4px}.layui-col-space10{margin:-5px}.layui-col-space10>*{padding:5px}.layui-col-space12{margin:-6px}.layui-col-space12>*{padding:6px}.layui-col-space14{margin:-7px}.layui-col-space14>*{padding:7px}.layui-col-space15{margin:-7.5px}.layui-col-space15>*{padding:7.5px}.layui-col-space16{margin:-8px}.layui-col-space16>*{padding:8px}.layui-col-space18{margin:-9px}.layui-col-space18>*{padding:9px}.layui-col-space20{margin:-10px}.layui-col-space20>*{padding:10px}.layui-col-space22{margin:-11px}.layui-col-space22>*{padding:11px}.layui-col-space24{margin:-12px}.layui-col-space24>*{padding:12px}.layui-col-space25{margin:-12.5px}.layui-col-space25>*{padding:12.5px}.layui-col-space26{margin:-13px}.layui-col-space26>*{padding:13px}.layui-col-space28{margin:-14px}.layui-col-space28>*{padding:14px}.layui-col-space30{margin:-15px}.layui-col-space30>*{padding:15px}.layui-btn,.layui-input,.layui-select,.layui-textarea,.layui-upload-button{outline:0;-webkit-appearance:none;transition:all .3s;-webkit-transition:all .3s;box-sizing:border-box}.layui-elem-quote{margin-bottom:10px;padding:15px;line-height:22px;border-left:5px solid #009688;border-radius:0 2px 2px 0;background-color:#f2f2f2}.layui-quote-nm{border-style:solid;border-width:1px 1px 1px 5px;background:0 0}.layui-elem-field{margin-bottom:10px;padding:0;border-width:1px;border-style:solid}.layui-elem-field legend{margin-left:20px;padding:0 10px;font-size:20px;font-weight:300}.layui-field-title{margin:10px 0 20px;border-width:1px 0 0}.layui-field-box{padding:10px 15px}.layui-field-title .layui-field-box{padding:10px 0}.layui-progress{position:relative;height:6px;border-radius:20px;background-color:#e2e2e2}.layui-progress-bar{position:absolute;left:0;top:0;width:0;max-width:100%;height:6px;border-radius:20px;text-align:right;background-color:#5FB878;transition:all .3s;-webkit-transition:all .3s}.layui-progress-big,.layui-progress-big .layui-progress-bar{height:18px;line-height:18px}.layui-progress-text{position:relative;top:-20px;line-height:18px;font-size:12px;color:#666}.layui-progress-big .layui-progress-text{position:static;padding:0 10px;color:#fff}.layui-collapse{border-width:1px;border-style:solid;border-radius:2px}.layui-colla-content,.layui-colla-item{border-top-width:1px;border-top-style:solid}.layui-colla-item:first-child{border-top:none}.layui-colla-title{position:relative;height:42px;line-height:42px;padding:0 15px 0 35px;color:#333;background-color:#f2f2f2;cursor:pointer;font-size:14px;overflow:hidden}.layui-colla-content{display:none;padding:10px 15px;line-height:22px;color:#666}.layui-colla-icon{position:absolute;left:15px;top:0;font-size:14px}.layui-card{margin-bottom:15px;border-radius:2px;background-color:#fff;box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.layui-card:last-child{margin-bottom:0}.layui-card-header{position:relative;height:42px;line-height:42px;padding:0 15px;border-bottom:1px solid #f6f6f6;color:#333;border-radius:2px 2px 0 0;font-size:14px}.layui-bg-black,.layui-bg-blue,.layui-bg-cyan,.layui-bg-green,.layui-bg-orange,.layui-bg-red{color:#fff!important}.layui-card-body{position:relative;padding:10px 15px;line-height:24px}.layui-card-body[pad15]{padding:15px}.layui-card-body[pad20]{padding:20px}.layui-card-body .layui-table{margin:5px 0}.layui-card .layui-tab{margin:0}.layui-panel-window{position:relative;padding:15px;border-radius:0;border-top:5px solid #E6E6E6;background-color:#fff}.layui-auxiliar-moving{position:fixed;left:0;right:0;top:0;bottom:0;width:100%;height:100%;background:0 0;z-index:9999999999}.layui-form-label,.layui-form-mid,.layui-form-select,.layui-input-block,.layui-input-inline,.layui-textarea{position:relative}.layui-bg-red{background-color:#FF5722!important}.layui-bg-orange{background-color:#FFB800!important}.layui-bg-green{background-color:#009688!important}.layui-bg-cyan{background-color:#2F4056!important}.layui-bg-blue{background-color:#1E9FFF!important}.layui-bg-black{background-color:#393D49!important}.layui-bg-gray{background-color:#eee!important;color:#666!important}.layui-badge-rim,.layui-colla-content,.layui-colla-item,.layui-collapse,.layui-elem-field,.layui-form-pane .layui-form-item[pane],.layui-form-pane .layui-form-label,.layui-input,.layui-layedit,.layui-layedit-tool,.layui-quote-nm,.layui-select,.layui-tab-bar,.layui-tab-card,.layui-tab-title,.layui-tab-title .layui-this:after,.layui-textarea{border-color:#e6e6e6}.layui-timeline-item:before,hr{background-color:#e6e6e6}.layui-text{line-height:22px;font-size:14px;color:#666}.layui-text h1,.layui-text h2,.layui-text h3{font-weight:500;color:#333}.layui-text h1{font-size:30px}.layui-text h2{font-size:24px}.layui-text h3{font-size:18px}.layui-text a:not(.layui-btn){color:#01AAED}.layui-text a:not(.layui-btn):hover{text-decoration:underline}.layui-text ul{padding:5px 0 5px 15px}.layui-text ul li{margin-top:5px;list-style-type:disc}.layui-text em,.layui-word-aux{color:#999!important;padding:0 5px!important}.layui-btn{display:inline-block;height:38px;line-height:38px;padding:0 18px;background-color:#009688;color:#fff;white-space:nowrap;text-align:center;font-size:14px;border:none;border-radius:2px;cursor:pointer}.layui-btn:hover{opacity:.8;filter:alpha(opacity=80);color:#fff}.layui-btn:active{opacity:1;filter:alpha(opacity=100)}.layui-btn+.layui-btn{margin-left:10px}.layui-btn-container{font-size:0}.layui-btn-container .layui-btn{margin-right:10px;margin-bottom:10px}.layui-btn-container .layui-btn+.layui-btn{margin-left:0}.layui-table .layui-btn-container .layui-btn{margin-bottom:9px}.layui-btn-radius{border-radius:100px}.layui-btn .layui-icon{margin-right:3px;font-size:18px;vertical-align:bottom;vertical-align:middle\9}.layui-btn-primary{border:1px solid #C9C9C9;background-color:#fff;color:#555}.layui-btn-primary:hover{border-color:#009688;color:#333}.layui-btn-normal{background-color:#1E9FFF}.layui-btn-warm{background-color:#FFB800}.layui-btn-danger{background-color:#FF5722}.layui-btn-checked{background-color:#5FB878}.layui-btn-disabled,.layui-btn-disabled:active,.layui-btn-disabled:hover{border:1px solid #e6e6e6;background-color:#FBFBFB;color:#C9C9C9;cursor:not-allowed;opacity:1}.layui-btn-lg{height:44px;line-height:44px;padding:0 25px;font-size:16px}.layui-btn-sm{height:30px;line-height:30px;padding:0 10px;font-size:12px}.layui-btn-sm i{font-size:16px!important}.layui-btn-xs{height:22px;line-height:22px;padding:0 5px;font-size:12px}.layui-btn-xs i{font-size:14px!important}.layui-btn-group{display:inline-block;vertical-align:middle;font-size:0}.layui-btn-group .layui-btn{margin-left:0!important;margin-right:0!important;border-left:1px solid rgba(255,255,255,.5);border-radius:0}.layui-btn-group .layui-btn-primary{border-left:none}.layui-btn-group .layui-btn-primary:hover{border-color:#C9C9C9;color:#009688}.layui-btn-group .layui-btn:first-child{border-left:none;border-radius:2px 0 0 2px}.layui-btn-group .layui-btn-primary:first-child{border-left:1px solid #c9c9c9}.layui-btn-group .layui-btn:last-child{border-radius:0 2px 2px 0}.layui-btn-group .layui-btn+.layui-btn{margin-left:0}.layui-btn-group+.layui-btn-group{margin-left:10px}.layui-btn-fluid{width:100%}.layui-input,.layui-select,.layui-textarea{height:38px;line-height:1.3;line-height:38px\9;border-width:1px;border-style:solid;background-color:#fff;border-radius:2px}.layui-input::-webkit-input-placeholder,.layui-select::-webkit-input-placeholder,.layui-textarea::-webkit-input-placeholder{line-height:1.3}.layui-input,.layui-textarea{display:block;width:100%;padding-left:10px}.layui-input:hover,.layui-textarea:hover{border-color:#D2D2D2!important}.layui-input:focus,.layui-textarea:focus{border-color:#C9C9C9!important}.layui-textarea{min-height:100px;height:auto;line-height:20px;padding:6px 10px;resize:vertical}.layui-select{padding:0 10px}.layui-form input[type=checkbox],.layui-form input[type=radio],.layui-form select{display:none}.layui-form [lay-ignore]{display:initial}.layui-form-item{margin-bottom:15px;clear:both;*zoom:1}.layui-form-item:after{content:'\20';clear:both;*zoom:1;display:block;height:0}.layui-form-label{float:left;display:block;padding:9px 15px;width:80px;font-weight:400;line-height:20px;text-align:right}.layui-form-label-col{display:block;float:none;padding:9px 0;line-height:20px;text-align:left}.layui-form-item .layui-inline{margin-bottom:5px;margin-right:10px}.layui-input-block{margin-left:110px;min-height:36px}.layui-input-inline{display:inline-block;vertical-align:middle}.layui-form-item .layui-input-inline{float:left;width:190px;margin-right:10px}.layui-form-text .layui-input-inline{width:auto}.layui-form-mid{float:left;display:block;padding:9px 0!important;line-height:20px;margin-right:10px}.layui-form-danger+.layui-form-select .layui-input,.layui-form-danger:focus{border-color:#FF5722!important}.layui-form-select .layui-input{padding-right:30px;cursor:pointer}.layui-form-select .layui-edge{position:absolute;right:10px;top:50%;margin-top:-3px;cursor:pointer;border-width:6px;border-top-color:#c2c2c2;border-top-style:solid;transition:all .3s;-webkit-transition:all .3s}.layui-form-select dl{display:none;position:absolute;left:0;top:42px;padding:5px 0;z-index:899;min-width:100%;border:1px solid #d2d2d2;max-height:300px;overflow-y:auto;background-color:#fff;border-radius:2px;box-shadow:0 2px 4px rgba(0,0,0,.12);box-sizing:border-box}.layui-form-select dl dd,.layui-form-select dl dt{padding:0 10px;line-height:36px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.layui-form-select dl dt{font-size:12px;color:#999}.layui-form-select dl dd{cursor:pointer}.layui-form-select dl dd:hover{background-color:#f2f2f2;-webkit-transition:.5s all;transition:.5s all}.layui-form-select .layui-select-group dd{padding-left:20px}.layui-form-select dl dd.layui-select-tips{padding-left:10px!important;color:#999}.layui-form-select dl dd.layui-this{background-color:#5FB878;color:#fff}.layui-form-checkbox,.layui-form-select dl dd.layui-disabled{background-color:#fff}.layui-form-selected dl{display:block}.layui-form-checkbox,.layui-form-checkbox *,.layui-form-switch{display:inline-block;vertical-align:middle}.layui-form-selected .layui-edge{margin-top:-9px;-webkit-transform:rotate(180deg);transform:rotate(180deg);margin-top:-3px\9}:root .layui-form-selected .layui-edge{margin-top:-9px\0/IE9}.layui-form-selectup dl{top:auto;bottom:42px}.layui-select-none{margin:5px 0;text-align:center;color:#999}.layui-select-disabled .layui-disabled{border-color:#eee!important}.layui-select-disabled .layui-edge{border-top-color:#d2d2d2}.layui-form-checkbox{position:relative;height:30px;line-height:30px;margin-right:10px;padding-right:30px;cursor:pointer;font-size:0;-webkit-transition:.1s linear;transition:.1s linear;box-sizing:border-box}.layui-form-checkbox span{padding:0 10px;height:100%;font-size:14px;border-radius:2px 0 0 2px;background-color:#d2d2d2;color:#fff;overflow:hidden}.layui-form-checkbox:hover span{background-color:#c2c2c2}.layui-form-checkbox i{position:absolute;right:0;top:0;width:30px;height:28px;border:1px solid #d2d2d2;border-left:none;border-radius:0 2px 2px 0;color:#fff;font-size:20px;text-align:center}.layui-form-checkbox:hover i{border-color:#c2c2c2;color:#c2c2c2}.layui-form-checked,.layui-form-checked:hover{border-color:#5FB878}.layui-form-checked span,.layui-form-checked:hover span{background-color:#5FB878}.layui-form-checked i,.layui-form-checked:hover i{color:#5FB878}.layui-form-item .layui-form-checkbox{margin-top:4px}.layui-form-checkbox[lay-skin=primary]{height:auto!important;line-height:normal!important;min-width:18px;min-height:18px;border:none!important;margin-right:0;padding-left:28px;padding-right:0;background:0 0}.layui-form-checkbox[lay-skin=primary] span{padding-left:0;padding-right:15px;line-height:18px;background:0 0;color:#666}.layui-form-checkbox[lay-skin=primary] i{right:auto;left:0;width:16px;height:16px;line-height:16px;border:1px solid #d2d2d2;font-size:12px;border-radius:2px;background-color:#fff;-webkit-transition:.1s linear;transition:.1s linear}.layui-form-checkbox[lay-skin=primary]:hover i{border-color:#5FB878;color:#fff}.layui-form-checked[lay-skin=primary] i{border-color:#5FB878!important;background-color:#5FB878;color:#fff}.layui-checkbox-disbaled[lay-skin=primary] span{background:0 0!important;color:#c2c2c2}.layui-checkbox-disbaled[lay-skin=primary]:hover i{border-color:#d2d2d2}.layui-form-item .layui-form-checkbox[lay-skin=primary]{margin-top:10px}.layui-form-switch{position:relative;height:22px;line-height:22px;min-width:35px;padding:0 5px;margin-top:8px;border:1px solid #d2d2d2;border-radius:20px;cursor:pointer;background-color:#fff;-webkit-transition:.1s linear;transition:.1s linear}.layui-form-switch i{position:absolute;left:5px;top:3px;width:16px;height:16px;border-radius:20px;background-color:#d2d2d2;-webkit-transition:.1s linear;transition:.1s linear}.layui-form-switch em{position:relative;top:0;width:25px;margin-left:21px;padding:0!important;text-align:center!important;color:#999!important;font-style:normal!important;font-size:12px}.layui-form-onswitch{border-color:#5FB878;background-color:#5FB878}.layui-checkbox-disbaled,.layui-checkbox-disbaled i{border-color:#e2e2e2!important}.layui-form-onswitch i{left:100%;margin-left:-21px;background-color:#fff}.layui-form-onswitch em{margin-left:5px;margin-right:21px;color:#fff!important}.layui-checkbox-disbaled span{background-color:#e2e2e2!important}.layui-checkbox-disbaled:hover i{color:#fff!important}[lay-radio]{display:none}.layui-form-radio,.layui-form-radio *{display:inline-block;vertical-align:middle}.layui-form-radio{line-height:28px;margin:6px 10px 0 0;padding-right:10px;cursor:pointer;font-size:0}.layui-form-radio *{font-size:14px}.layui-form-radio>i{margin-right:8px;font-size:22px;color:#c2c2c2}.layui-form-radio>i:hover,.layui-form-radioed>i{color:#5FB878}.layui-radio-disbaled>i{color:#e2e2e2!important}.layui-form-pane .layui-form-label{width:110px;padding:8px 15px;height:38px;line-height:20px;border-width:1px;border-style:solid;border-radius:2px 0 0 2px;text-align:center;background-color:#FBFBFB;overflow:hidden;box-sizing:border-box}.layui-form-pane .layui-input-inline{margin-left:-1px}.layui-form-pane .layui-input-block{margin-left:110px;left:-1px}.layui-form-pane .layui-input{border-radius:0 2px 2px 0}.layui-form-pane .layui-form-text .layui-form-label{float:none;width:100%;border-radius:2px;box-sizing:border-box;text-align:left}.layui-form-pane .layui-form-text .layui-input-inline{display:block;margin:0;top:-1px;clear:both}.layui-form-pane .layui-form-text .layui-input-block{margin:0;left:0;top:-1px}.layui-form-pane .layui-form-text .layui-textarea{min-height:100px;border-radius:0 0 2px 2px}.layui-form-pane .layui-form-checkbox{margin:4px 0 4px 10px}.layui-form-pane .layui-form-radio,.layui-form-pane .layui-form-switch{margin-top:6px;margin-left:10px}.layui-form-pane .layui-form-item[pane]{position:relative;border-width:1px;border-style:solid}.layui-form-pane .layui-form-item[pane] .layui-form-label{position:absolute;left:0;top:0;height:100%;border-width:0 1px 0 0}.layui-form-pane .layui-form-item[pane] .layui-input-inline{margin-left:110px}@media screen and (max-width:450px){.layui-form-item .layui-form-label{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-form-item .layui-inline{display:block;margin-right:0;margin-bottom:20px;clear:both}.layui-form-item .layui-inline:after{content:'\20';clear:both;display:block;height:0}.layui-form-item .layui-input-inline{display:block;float:none;left:-3px;width:auto;margin:0 0 10px 112px}.layui-form-item .layui-input-inline+.layui-form-mid{margin-left:110px;top:-5px;padding:0}.layui-form-item .layui-form-checkbox{margin-right:5px;margin-bottom:5px}}.layui-layedit{border-width:1px;border-style:solid;border-radius:2px}.layui-layedit-tool{padding:3px 5px;border-bottom-width:1px;border-bottom-style:solid;font-size:0}.layedit-tool-fixed{position:fixed;top:0;border-top:1px solid #e2e2e2}.layui-layedit-tool .layedit-tool-mid,.layui-layedit-tool .layui-icon{display:inline-block;vertical-align:middle;text-align:center;font-size:14px}.layui-layedit-tool .layui-icon{position:relative;width:32px;height:30px;line-height:30px;margin:3px 5px;color:#777;cursor:pointer;border-radius:2px}.layui-layedit-tool .layui-icon:hover{color:#393D49}.layui-layedit-tool .layui-icon:active{color:#000}.layui-layedit-tool .layedit-tool-active{background-color:#e2e2e2;color:#000}.layui-layedit-tool .layui-disabled,.layui-layedit-tool .layui-disabled:hover{color:#d2d2d2;cursor:not-allowed}.layui-layedit-tool .layedit-tool-mid{width:1px;height:18px;margin:0 10px;background-color:#d2d2d2}.layedit-tool-html{width:50px!important;font-size:30px!important}.layedit-tool-b,.layedit-tool-code,.layedit-tool-help{font-size:16px!important}.layedit-tool-d,.layedit-tool-face,.layedit-tool-image,.layedit-tool-unlink{font-size:18px!important}.layedit-tool-image input{position:absolute;font-size:0;left:0;top:0;width:100%;height:100%;opacity:.01;filter:Alpha(opacity=1);cursor:pointer}.layui-layedit-iframe iframe{display:block;width:100%}#LAY_layedit_code{overflow:hidden}.layui-laypage{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;margin:10px 0;font-size:0}.layui-laypage>a:first-child,.layui-laypage>a:first-child em{border-radius:2px 0 0 2px}.layui-laypage>a:last-child,.layui-laypage>a:last-child em{border-radius:0 2px 2px 0}.layui-laypage>:first-child{margin-left:0!important}.layui-laypage>:last-child{margin-right:0!important}.layui-laypage a,.layui-laypage button,.layui-laypage input,.layui-laypage select,.layui-laypage span{border:1px solid #e2e2e2}.layui-laypage a,.layui-laypage span{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding:0 15px;height:28px;line-height:28px;margin:0 -1px 5px 0;background-color:#fff;color:#333;font-size:12px}.layui-flow-more a *,.layui-laypage input,.layui-table-view select[lay-ignore]{display:inline-block}.layui-laypage a:hover{color:#009688}.layui-laypage em{font-style:normal}.layui-laypage .layui-laypage-spr{color:#999;font-weight:700}.layui-laypage a{text-decoration:none}.layui-laypage .layui-laypage-curr{position:relative}.layui-laypage .layui-laypage-curr em{position:relative;color:#fff}.layui-laypage .layui-laypage-curr .layui-laypage-em{position:absolute;left:-1px;top:-1px;padding:1px;width:100%;height:100%;background-color:#009688}.layui-laypage-em{border-radius:2px}.layui-laypage-next em,.layui-laypage-prev em{font-family:Sim sun;font-size:16px}.layui-laypage .layui-laypage-count,.layui-laypage .layui-laypage-limits,.layui-laypage .layui-laypage-refresh,.layui-laypage .layui-laypage-skip{margin-left:10px;margin-right:10px;padding:0;border:none}.layui-laypage .layui-laypage-limits,.layui-laypage .layui-laypage-refresh{vertical-align:top}.layui-laypage .layui-laypage-refresh i{font-size:18px;cursor:pointer}.layui-laypage select{height:22px;padding:3px;border-radius:2px;cursor:pointer}.layui-laypage .layui-laypage-skip{height:30px;line-height:30px;color:#999}.layui-laypage button,.layui-laypage input{height:30px;line-height:30px;border-radius:2px;vertical-align:top;background-color:#fff;box-sizing:border-box}.layui-laypage input{width:40px;margin:0 10px;padding:0 3px;text-align:center}.layui-laypage input:focus,.layui-laypage select:focus{border-color:#009688!important}.layui-laypage button{margin-left:10px;padding:0 10px;cursor:pointer}.layui-table,.layui-table-view{margin:10px 0}.layui-flow-more{margin:10px 0;text-align:center;color:#999;font-size:14px}.layui-flow-more a{height:32px;line-height:32px}.layui-flow-more a *{vertical-align:top}.layui-flow-more a cite{padding:0 20px;border-radius:3px;background-color:#eee;color:#333;font-style:normal}.layui-flow-more a cite:hover{opacity:.8}.layui-flow-more a i{font-size:30px;color:#737383}.layui-table{width:100%;background-color:#fff;color:#666}.layui-table tr{transition:all .3s;-webkit-transition:all .3s}.layui-table th{text-align:left;font-weight:400}.layui-table tbody tr:hover,.layui-table thead tr,.layui-table-click,.layui-table-header,.layui-table-hover,.layui-table-mend,.layui-table-patch,.layui-table-tool,.layui-table-total,.layui-table-total tr,.layui-table[lay-even] tr:nth-child(even){background-color:#f2f2f2}.layui-table td,.layui-table th,.layui-table-col-set,.layui-table-fixed-r,.layui-table-grid-down,.layui-table-header,.layui-table-page,.layui-table-tips-main,.layui-table-tool,.layui-table-total,.layui-table-view,.layui-table[lay-skin=line],.layui-table[lay-skin=row]{border-width:1px;border-style:solid;border-color:#e6e6e6}.layui-table td,.layui-table th{position:relative;padding:9px 15px;min-height:20px;line-height:20px;font-size:14px}.layui-table[lay-skin=line] td,.layui-table[lay-skin=line] th{border-width:0 0 1px}.layui-table[lay-skin=row] td,.layui-table[lay-skin=row] th{border-width:0 1px 0 0}.layui-table[lay-skin=nob] td,.layui-table[lay-skin=nob] th{border:none}.layui-table img{max-width:100px}.layui-table[lay-size=lg] td,.layui-table[lay-size=lg] th{padding:15px 30px}.layui-table-view .layui-table[lay-size=lg] .layui-table-cell{height:40px;line-height:40px}.layui-table[lay-size=sm] td,.layui-table[lay-size=sm] th{font-size:12px;padding:5px 10px}.layui-table-view .layui-table[lay-size=sm] .layui-table-cell{height:20px;line-height:20px}.layui-table[lay-data]{display:none}.layui-table-box{position:relative;overflow:hidden}.layui-table-view .layui-table{position:relative;width:auto;margin:0}.layui-table-view .layui-table[lay-skin=line]{border-width:0 1px 0 0}.layui-table-view .layui-table[lay-skin=row]{border-width:0 0 1px}.layui-table-view .layui-table td,.layui-table-view .layui-table th{padding:5px 0;border-top:none;border-left:none}.layui-table-view .layui-table th.layui-unselect .layui-table-cell span{cursor:pointer}.layui-table-view .layui-table td{cursor:default}.layui-table-view .layui-table td[data-edit=text]{cursor:text}.layui-table-view .layui-form-checkbox[lay-skin=primary] i{width:18px;height:18px}.layui-table-view .layui-form-radio{line-height:0;padding:0}.layui-table-view .layui-form-radio>i{margin:0;font-size:20px}.layui-table-init{position:absolute;left:0;top:0;width:100%;height:100%;text-align:center;z-index:110}.layui-table-init .layui-icon{position:absolute;left:50%;top:50%;margin:-15px 0 0 -15px;font-size:30px;color:#c2c2c2}.layui-table-header{border-width:0 0 1px;overflow:hidden}.layui-table-header .layui-table{margin-bottom:-1px}.layui-table-tool .layui-inline[lay-event]{position:relative;width:26px;height:26px;padding:5px;line-height:16px;margin-right:10px;text-align:center;color:#333;border:1px solid #ccc;cursor:pointer;-webkit-transition:.5s all;transition:.5s all}.layui-table-tool .layui-inline[lay-event]:hover{border:1px solid #999}.layui-table-tool-temp{padding-right:120px}.layui-table-tool-self{position:absolute;right:17px;top:10px}.layui-table-tool .layui-table-tool-self .layui-inline[lay-event]{margin:0 0 0 10px}.layui-table-tool-panel{position:absolute;top:29px;left:-1px;padding:5px 0;min-width:150px;min-height:40px;border:1px solid #d2d2d2;text-align:left;overflow-y:auto;background-color:#fff;box-shadow:0 2px 4px rgba(0,0,0,.12)}.layui-table-cell,.layui-table-tool-panel li{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.layui-table-tool-panel li{padding:0 10px;line-height:30px;-webkit-transition:.5s all;transition:.5s all}.layui-table-tool-panel li .layui-form-checkbox[lay-skin=primary]{width:100%;padding-left:28px}.layui-table-tool-panel li:hover{background-color:#f2f2f2}.layui-table-tool-panel li .layui-form-checkbox[lay-skin=primary] i{position:absolute;left:0;top:0}.layui-table-tool-panel li .layui-form-checkbox[lay-skin=primary] span{padding:0}.layui-table-tool .layui-table-tool-self .layui-table-tool-panel{left:auto;right:-1px}.layui-table-col-set{position:absolute;right:0;top:0;width:20px;height:100%;border-width:0 0 0 1px;background-color:#fff}.layui-table-sort{width:10px;height:20px;margin-left:5px;cursor:pointer!important}.layui-table-sort .layui-edge{position:absolute;left:5px;border-width:5px}.layui-table-sort .layui-table-sort-asc{top:3px;border-top:none;border-bottom-style:solid;border-bottom-color:#b2b2b2}.layui-table-sort .layui-table-sort-asc:hover{border-bottom-color:#666}.layui-table-sort .layui-table-sort-desc{bottom:5px;border-bottom:none;border-top-style:solid;border-top-color:#b2b2b2}.layui-table-sort .layui-table-sort-desc:hover{border-top-color:#666}.layui-table-sort[lay-sort=asc] .layui-table-sort-asc{border-bottom-color:#000}.layui-table-sort[lay-sort=desc] .layui-table-sort-desc{border-top-color:#000}.layui-table-cell{height:28px;line-height:28px;padding:0 15px;position:relative;box-sizing:border-box}.layui-table-cell .layui-form-checkbox[lay-skin=primary]{top:-1px;padding:0}.layui-table-cell .layui-table-link{color:#01AAED}.laytable-cell-checkbox,.laytable-cell-numbers,.laytable-cell-radio,.laytable-cell-space{padding:0;text-align:center}.layui-table-body{position:relative;overflow:auto;margin-right:-1px;margin-bottom:-1px}.layui-table-body .layui-none{line-height:26px;padding:15px;text-align:center;color:#999}.layui-table-fixed{position:absolute;left:0;top:0;z-index:101}.layui-table-fixed .layui-table-body{overflow:hidden}.layui-table-fixed-l{box-shadow:0 -1px 8px rgba(0,0,0,.08)}.layui-table-fixed-r{left:auto;right:-1px;border-width:0 0 0 1px;box-shadow:-1px 0 8px rgba(0,0,0,.08)}.layui-table-fixed-r .layui-table-header{position:relative;overflow:visible}.layui-table-mend{position:absolute;right:-49px;top:0;height:100%;width:50px}.layui-table-tool{position:relative;z-index:890;width:100%;min-height:50px;line-height:30px;padding:10px 15px;border-width:0 0 1px}.layui-table-tool .layui-btn-container{margin-bottom:-10px}.layui-table-page,.layui-table-total{border-width:1px 0 0;margin-bottom:-1px;overflow:hidden}.layui-table-page{position:relative;width:100%;padding:7px 7px 0;height:41px;font-size:12px;white-space:nowrap}.layui-table-page>div{height:26px}.layui-table-page .layui-laypage{margin:0}.layui-table-page .layui-laypage a,.layui-table-page .layui-laypage span{height:26px;line-height:26px;margin-bottom:10px;border:none;background:0 0}.layui-table-page .layui-laypage a,.layui-table-page .layui-laypage span.layui-laypage-curr{padding:0 12px}.layui-table-page .layui-laypage span{margin-left:0;padding:0}.layui-table-page .layui-laypage .layui-laypage-prev{margin-left:-7px!important}.layui-table-page .layui-laypage .layui-laypage-curr .layui-laypage-em{left:0;top:0;padding:0}.layui-table-page .layui-laypage button,.layui-table-page .layui-laypage input{height:26px;line-height:26px}.layui-table-page .layui-laypage input{width:40px}.layui-table-page .layui-laypage button{padding:0 10px}.layui-table-page select{height:18px}.layui-table-patch .layui-table-cell{padding:0;width:30px}.layui-table-edit{position:absolute;left:0;top:0;width:100%;height:100%;padding:0 14px 1px;border-radius:0;box-shadow:1px 1px 20px rgba(0,0,0,.15)}.layui-table-edit:focus{border-color:#5FB878!important}select.layui-table-edit{padding:0 0 0 10px;border-color:#C9C9C9}.layui-table-view .layui-form-checkbox,.layui-table-view .layui-form-radio,.layui-table-view .layui-form-switch{top:0;margin:0;box-sizing:content-box}.layui-table-view .layui-form-checkbox{top:-1px;height:26px;line-height:26px}.layui-table-view .layui-form-checkbox i{height:26px}.layui-table-grid .layui-table-cell{overflow:visible}.layui-table-grid-down{position:absolute;top:0;right:0;width:26px;height:100%;padding:5px 0;border-width:0 0 0 1px;text-align:center;background-color:#fff;color:#999;cursor:pointer}.layui-table-grid-down .layui-icon{position:absolute;top:50%;left:50%;margin:-8px 0 0 -8px}.layui-table-grid-down:hover{background-color:#fbfbfb}body .layui-table-tips .layui-layer-content{background:0 0;padding:0;box-shadow:0 1px 6px rgba(0,0,0,.12)}.layui-table-tips-main{margin:-44px 0 0 -1px;max-height:150px;padding:8px 15px;font-size:14px;overflow-y:scroll;background-color:#fff;color:#666}.layui-table-tips-c{position:absolute;right:-3px;top:-13px;width:20px;height:20px;padding:3px;cursor:pointer;background-color:#666;border-radius:50%;color:#fff}.layui-table-tips-c:hover{background-color:#777}.layui-table-tips-c:before{position:relative;right:-2px}.layui-upload-file{display:none!important;opacity:.01;filter:Alpha(opacity=1)}.layui-upload-drag,.layui-upload-form,.layui-upload-wrap{display:inline-block}.layui-upload-list{margin:10px 0}.layui-upload-choose{padding:0 10px;color:#999}.layui-upload-drag{position:relative;padding:30px;border:1px dashed #e2e2e2;background-color:#fff;text-align:center;cursor:pointer;color:#999}.layui-upload-drag .layui-icon{font-size:50px;color:#009688}.layui-upload-drag[lay-over]{border-color:#009688}.layui-upload-iframe{position:absolute;width:0;height:0;border:0;visibility:hidden}.layui-upload-wrap{position:relative;vertical-align:middle}.layui-upload-wrap .layui-upload-file{display:block!important;position:absolute;left:0;top:0;z-index:10;font-size:100px;width:100%;height:100%;opacity:.01;filter:Alpha(opacity=1);cursor:pointer}.layui-transfer-active,.layui-transfer-box{display:inline-block;vertical-align:middle}.layui-transfer-box,.layui-transfer-header,.layui-transfer-search{border-width:0;border-style:solid;border-color:#e6e6e6}.layui-transfer-box{position:relative;border-width:1px;width:200px;height:360px;border-radius:2px;background-color:#fff}.layui-transfer-box .layui-form-checkbox{width:100%;margin:0!important}.layui-transfer-header{height:38px;line-height:38px;padding:0 10px;border-bottom-width:1px}.layui-transfer-search{position:relative;padding:10px;border-bottom-width:1px}.layui-transfer-search .layui-input{height:32px;padding-left:30px;font-size:12px}.layui-transfer-search .layui-icon-search{position:absolute;left:20px;top:50%;margin-top:-8px;color:#666}.layui-transfer-active{margin:0 15px}.layui-transfer-active .layui-btn{display:block;margin:0;padding:0 15px;background-color:#5FB878;border-color:#5FB878;color:#fff}.layui-transfer-active .layui-btn-disabled{background-color:#FBFBFB;border-color:#e6e6e6;color:#C9C9C9}.layui-transfer-active .layui-btn:first-child{margin-bottom:15px}.layui-transfer-active .layui-btn .layui-icon{margin:0;font-size:14px!important}.layui-transfer-data{padding:5px 0;overflow:auto}.layui-transfer-data li{height:32px;line-height:32px;padding:0 10px}.layui-transfer-data li:hover{background-color:#f2f2f2;transition:.5s all}.layui-transfer-data .layui-none{padding:15px 10px;text-align:center;color:#999}.layui-nav{position:relative;padding:0 20px;background-color:#393D49;color:#fff;border-radius:2px;font-size:0;box-sizing:border-box}.layui-nav *{font-size:14px}.layui-nav .layui-nav-item{position:relative;display:inline-block;*display:inline;*zoom:1;vertical-align:middle;line-height:60px}.layui-nav .layui-nav-item a{display:block;padding:0 20px;color:#fff;color:rgba(255,255,255,.7);transition:all .3s;-webkit-transition:all .3s}.layui-nav .layui-this:after,.layui-nav-bar,.layui-nav-tree .layui-nav-itemed:after{position:absolute;left:0;top:0;width:0;height:5px;background-color:#5FB878;transition:all .2s;-webkit-transition:all .2s}.layui-nav-bar{z-index:1000}.layui-nav .layui-nav-item a:hover,.layui-nav .layui-this a{color:#fff}.layui-nav .layui-this:after{content:'';top:auto;bottom:0;width:100%}.layui-nav-img{width:30px;height:30px;margin-right:10px;border-radius:50%}.layui-nav .layui-nav-more{content:'';width:0;height:0;border-style:solid dashed dashed;border-color:#fff transparent transparent;overflow:hidden;cursor:pointer;transition:all .2s;-webkit-transition:all .2s;position:absolute;top:50%;right:3px;margin-top:-3px;border-width:6px;border-top-color:rgba(255,255,255,.7)}.layui-nav .layui-nav-mored,.layui-nav-itemed>a .layui-nav-more{margin-top:-9px;border-style:dashed dashed solid;border-color:transparent transparent #fff}.layui-nav-child{display:none;position:absolute;left:0;top:65px;min-width:100%;line-height:36px;padding:5px 0;box-shadow:0 2px 4px rgba(0,0,0,.12);border:1px solid #d2d2d2;background-color:#fff;z-index:100;border-radius:2px;white-space:nowrap}.layui-nav .layui-nav-child a{color:#333}.layui-nav .layui-nav-child a:hover{background-color:#f2f2f2;color:#000}.layui-nav-child dd{position:relative}.layui-nav .layui-nav-child dd.layui-this a,.layui-nav-child dd.layui-this{background-color:#5FB878;color:#fff}.layui-nav-child dd.layui-this:after{display:none}.layui-nav-tree{width:200px;padding:0}.layui-nav-tree .layui-nav-item{display:block;width:100%;line-height:45px}.layui-nav-tree .layui-nav-item a{position:relative;height:45px;line-height:45px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-nav-tree .layui-nav-item a:hover{background-color:#4E5465}.layui-nav-tree .layui-nav-bar{width:5px;height:0;background-color:#009688}.layui-nav-tree .layui-nav-child dd.layui-this,.layui-nav-tree .layui-nav-child dd.layui-this a,.layui-nav-tree .layui-this,.layui-nav-tree .layui-this>a,.layui-nav-tree .layui-this>a:hover{background-color:#009688;color:#fff}.layui-nav-tree .layui-this:after{display:none}.layui-nav-itemed>a,.layui-nav-tree .layui-nav-title a,.layui-nav-tree .layui-nav-title a:hover{color:#fff!important}.layui-nav-tree .layui-nav-child{position:relative;z-index:0;top:0;border:none;box-shadow:none}.layui-nav-tree .layui-nav-child a{height:40px;line-height:40px;color:#fff;color:rgba(255,255,255,.7)}.layui-nav-tree .layui-nav-child,.layui-nav-tree .layui-nav-child a:hover{background:0 0;color:#fff}.layui-nav-tree .layui-nav-more{right:10px}.layui-nav-itemed>.layui-nav-child{display:block;padding:0;background-color:rgba(0,0,0,.3)!important}.layui-nav-itemed>.layui-nav-child>.layui-this>.layui-nav-child{display:block}.layui-nav-side{position:fixed;top:0;bottom:0;left:0;overflow-x:hidden;z-index:999}.layui-bg-blue .layui-nav-bar,.layui-bg-blue .layui-nav-itemed:after,.layui-bg-blue .layui-this:after{background-color:#93D1FF}.layui-bg-blue .layui-nav-child dd.layui-this{background-color:#1E9FFF}.layui-bg-blue .layui-nav-itemed>a,.layui-nav-tree.layui-bg-blue .layui-nav-title a,.layui-nav-tree.layui-bg-blue .layui-nav-title a:hover{background-color:#007DDB!important}.layui-breadcrumb{font-size:0}.layui-breadcrumb>*{font-size:14px}.layui-breadcrumb a{color:#999!important}.layui-breadcrumb a:hover{color:#5FB878!important}.layui-breadcrumb a cite{color:#666;font-style:normal}.layui-breadcrumb span[lay-separator]{margin:0 10px;color:#999}.layui-tab{margin:10px 0;text-align:left!important}.layui-tab[overflow]>.layui-tab-title{overflow:hidden}.layui-tab-title{position:relative;left:0;height:40px;white-space:nowrap;font-size:0;border-bottom-width:1px;border-bottom-style:solid;transition:all .2s;-webkit-transition:all .2s}.layui-tab-title li{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;font-size:14px;transition:all .2s;-webkit-transition:all .2s;position:relative;line-height:40px;min-width:65px;padding:0 15px;text-align:center;cursor:pointer}.layui-tab-title li a{display:block}.layui-tab-title .layui-this{color:#000}.layui-tab-title .layui-this:after{position:absolute;left:0;top:0;content:'';width:100%;height:41px;border-width:1px;border-style:solid;border-bottom-color:#fff;border-radius:2px 2px 0 0;box-sizing:border-box;pointer-events:none}.layui-tab-bar{position:absolute;right:0;top:0;z-index:10;width:30px;height:39px;line-height:39px;border-width:1px;border-style:solid;border-radius:2px;text-align:center;background-color:#fff;cursor:pointer}.layui-tab-bar .layui-icon{position:relative;display:inline-block;top:3px;transition:all .3s;-webkit-transition:all .3s}.layui-tab-item{display:none}.layui-tab-more{padding-right:30px;height:auto!important;white-space:normal!important}.layui-tab-more li.layui-this:after{border-bottom-color:#e2e2e2;border-radius:2px}.layui-tab-more .layui-tab-bar .layui-icon{top:-2px;top:3px\9;-webkit-transform:rotate(180deg);transform:rotate(180deg)}:root .layui-tab-more .layui-tab-bar .layui-icon{top:-2px\0/IE9}.layui-tab-content{padding:10px}.layui-tab-title li .layui-tab-close{position:relative;display:inline-block;width:18px;height:18px;line-height:20px;margin-left:8px;top:1px;text-align:center;font-size:14px;color:#c2c2c2;transition:all .2s;-webkit-transition:all .2s}.layui-tab-title li .layui-tab-close:hover{border-radius:2px;background-color:#FF5722;color:#fff}.layui-tab-brief>.layui-tab-title .layui-this{color:#009688}.layui-tab-brief>.layui-tab-more li.layui-this:after,.layui-tab-brief>.layui-tab-title .layui-this:after{border:none;border-radius:0;border-bottom:2px solid #5FB878}.layui-tab-brief[overflow]>.layui-tab-title .layui-this:after{top:-1px}.layui-tab-card{border-width:1px;border-style:solid;border-radius:2px;box-shadow:0 2px 5px 0 rgba(0,0,0,.1)}.layui-tab-card>.layui-tab-title{background-color:#f2f2f2}.layui-tab-card>.layui-tab-title li{margin-right:-1px;margin-left:-1px}.layui-tab-card>.layui-tab-title .layui-this{background-color:#fff}.layui-tab-card>.layui-tab-title .layui-this:after{border-top:none;border-width:1px;border-bottom-color:#fff}.layui-tab-card>.layui-tab-title .layui-tab-bar{height:40px;line-height:40px;border-radius:0;border-top:none;border-right:none}.layui-tab-card>.layui-tab-more .layui-this{background:0 0;color:#5FB878}.layui-tab-card>.layui-tab-more .layui-this:after{border:none}.layui-timeline{padding-left:5px}.layui-timeline-item{position:relative;padding-bottom:20px}.layui-timeline-axis{position:absolute;left:-5px;top:0;z-index:10;width:20px;height:20px;line-height:20px;background-color:#fff;color:#5FB878;border-radius:50%;text-align:center;cursor:pointer}.layui-timeline-axis:hover{color:#FF5722}.layui-timeline-item:before{content:'';position:absolute;left:5px;top:0;z-index:0;width:1px;height:100%}.layui-timeline-item:last-child:before{display:none}.layui-timeline-item:first-child:before{display:block}.layui-timeline-content{padding-left:25px}.layui-timeline-title{position:relative;margin-bottom:10px}.layui-badge,.layui-badge-dot,.layui-badge-rim{position:relative;display:inline-block;padding:0 6px;font-size:12px;text-align:center;background-color:#FF5722;color:#fff;border-radius:2px}.layui-badge{height:18px;line-height:18px}.layui-badge-dot{width:8px;height:8px;padding:0;border-radius:50%}.layui-badge-rim{height:18px;line-height:18px;border-width:1px;border-style:solid;background-color:#fff;color:#666}.layui-btn .layui-badge,.layui-btn .layui-badge-dot{margin-left:5px}.layui-nav .layui-badge,.layui-nav .layui-badge-dot{position:absolute;top:50%;margin:-8px 6px 0}.layui-tab-title .layui-badge,.layui-tab-title .layui-badge-dot{left:5px;top:-2px}.layui-carousel{position:relative;left:0;top:0;background-color:#f8f8f8}.layui-carousel>[carousel-item]{position:relative;width:100%;height:100%;overflow:hidden}.layui-carousel>[carousel-item]:before{position:absolute;content:'\e63d';left:50%;top:50%;width:100px;line-height:20px;margin:-10px 0 0 -50px;text-align:center;color:#c2c2c2;font-family:layui-icon!important;font-size:30px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.layui-carousel>[carousel-item]>*{display:none;position:absolute;left:0;top:0;width:100%;height:100%;background-color:#f8f8f8;transition-duration:.3s;-webkit-transition-duration:.3s}.layui-carousel-updown>*{-webkit-transition:.3s ease-in-out up;transition:.3s ease-in-out up}.layui-carousel-arrow{display:none\9;opacity:0;position:absolute;left:10px;top:50%;margin-top:-18px;width:36px;height:36px;line-height:36px;text-align:center;font-size:20px;border:0;border-radius:50%;background-color:rgba(0,0,0,.2);color:#fff;-webkit-transition-duration:.3s;transition-duration:.3s;cursor:pointer}.layui-carousel-arrow[lay-type=add]{left:auto!important;right:10px}.layui-carousel:hover .layui-carousel-arrow[lay-type=add],.layui-carousel[lay-arrow=always] .layui-carousel-arrow[lay-type=add]{right:20px}.layui-carousel[lay-arrow=always] .layui-carousel-arrow{opacity:1;left:20px}.layui-carousel[lay-arrow=none] .layui-carousel-arrow{display:none}.layui-carousel-arrow:hover,.layui-carousel-ind ul:hover{background-color:rgba(0,0,0,.35)}.layui-carousel:hover .layui-carousel-arrow{display:block\9;opacity:1;left:20px}.layui-carousel-ind{position:relative;top:-35px;width:100%;line-height:0!important;text-align:center;font-size:0}.layui-carousel[lay-indicator=outside]{margin-bottom:30px}.layui-carousel[lay-indicator=outside] .layui-carousel-ind{top:10px}.layui-carousel[lay-indicator=outside] .layui-carousel-ind ul{background-color:rgba(0,0,0,.5)}.layui-carousel[lay-indicator=none] .layui-carousel-ind{display:none}.layui-carousel-ind ul{display:inline-block;padding:5px;background-color:rgba(0,0,0,.2);border-radius:10px;-webkit-transition-duration:.3s;transition-duration:.3s}.layui-carousel-ind li{display:inline-block;width:10px;height:10px;margin:0 3px;font-size:14px;background-color:#e2e2e2;background-color:rgba(255,255,255,.5);border-radius:50%;cursor:pointer;-webkit-transition-duration:.3s;transition-duration:.3s}.layui-carousel-ind li:hover{background-color:rgba(255,255,255,.7)}.layui-carousel-ind li.layui-this{background-color:#fff}.layui-carousel>[carousel-item]>.layui-carousel-next,.layui-carousel>[carousel-item]>.layui-carousel-prev,.layui-carousel>[carousel-item]>.layui-this{display:block}.layui-carousel>[carousel-item]>.layui-this{left:0}.layui-carousel>[carousel-item]>.layui-carousel-prev{left:-100%}.layui-carousel>[carousel-item]>.layui-carousel-next{left:100%}.layui-carousel>[carousel-item]>.layui-carousel-next.layui-carousel-left,.layui-carousel>[carousel-item]>.layui-carousel-prev.layui-carousel-right{left:0}.layui-carousel>[carousel-item]>.layui-this.layui-carousel-left{left:-100%}.layui-carousel>[carousel-item]>.layui-this.layui-carousel-right{left:100%}.layui-carousel[lay-anim=updown] .layui-carousel-arrow{left:50%!important;top:20px;margin:0 0 0 -18px}.layui-carousel[lay-anim=updown]>[carousel-item]>*,.layui-carousel[lay-anim=fade]>[carousel-item]>*{left:0!important}.layui-carousel[lay-anim=updown] .layui-carousel-arrow[lay-type=add]{top:auto!important;bottom:20px}.layui-carousel[lay-anim=updown] .layui-carousel-ind{position:absolute;top:50%;right:20px;width:auto;height:auto}.layui-carousel[lay-anim=updown] .layui-carousel-ind ul{padding:3px 5px}.layui-carousel[lay-anim=updown] .layui-carousel-ind li{display:block;margin:6px 0}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-this{top:0}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-carousel-prev{top:-100%}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-carousel-next{top:100%}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-carousel-next.layui-carousel-left,.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-carousel-prev.layui-carousel-right{top:0}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-this.layui-carousel-left{top:-100%}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-this.layui-carousel-right{top:100%}.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-carousel-next,.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-carousel-prev{opacity:0}.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-carousel-next.layui-carousel-left,.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-carousel-prev.layui-carousel-right{opacity:1}.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-this.layui-carousel-left,.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-this.layui-carousel-right{opacity:0}.layui-fixbar{position:fixed;right:15px;bottom:15px;z-index:999999}.layui-fixbar li{width:50px;height:50px;line-height:50px;margin-bottom:1px;text-align:center;cursor:pointer;font-size:30px;background-color:#9F9F9F;color:#fff;border-radius:2px;opacity:.95}.layui-fixbar li:hover{opacity:.85}.layui-fixbar li:active{opacity:1}.layui-fixbar .layui-fixbar-top{display:none;font-size:40px}body .layui-util-face{border:none;background:0 0}body .layui-util-face .layui-layer-content{padding:0;background-color:#fff;color:#666;box-shadow:none}.layui-util-face .layui-layer-TipsG{display:none}.layui-util-face ul{position:relative;width:372px;padding:10px;border:1px solid #D9D9D9;background-color:#fff;box-shadow:0 0 20px rgba(0,0,0,.2)}.layui-util-face ul li{cursor:pointer;float:left;border:1px solid #e8e8e8;height:22px;width:26px;overflow:hidden;margin:-1px 0 0 -1px;padding:4px 2px;text-align:center}.layui-util-face ul li:hover{position:relative;z-index:2;border:1px solid #eb7350;background:#fff9ec}.layui-code{position:relative;margin:10px 0;padding:15px;line-height:20px;border:1px solid #ddd;border-left-width:6px;background-color:#F2F2F2;color:#333;font-family:Courier New;font-size:12px}.layui-rate,.layui-rate *{display:inline-block;vertical-align:middle}.layui-rate{padding:10px 5px 10px 0;font-size:0}.layui-rate li i.layui-icon{font-size:20px;color:#FFB800;margin-right:5px;transition:all .3s;-webkit-transition:all .3s}.layui-rate li i:hover{cursor:pointer;transform:scale(1.12);-webkit-transform:scale(1.12)}.layui-rate[readonly] li i:hover{cursor:default;transform:scale(1)}.layui-colorpicker{width:26px;height:26px;border:1px solid #e6e6e6;padding:5px;border-radius:2px;line-height:24px;display:inline-block;cursor:pointer;transition:all .3s;-webkit-transition:all .3s}.layui-colorpicker:hover{border-color:#d2d2d2}.layui-colorpicker.layui-colorpicker-lg{width:34px;height:34px;line-height:32px}.layui-colorpicker.layui-colorpicker-sm{width:24px;height:24px;line-height:22px}.layui-colorpicker.layui-colorpicker-xs{width:22px;height:22px;line-height:20px}.layui-colorpicker-trigger-bgcolor{display:block;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);border-radius:2px}.layui-colorpicker-trigger-span{display:block;height:100%;box-sizing:border-box;border:1px solid rgba(0,0,0,.15);border-radius:2px;text-align:center}.layui-colorpicker-trigger-i{display:inline-block;color:#FFF;font-size:12px}.layui-colorpicker-trigger-i.layui-icon-close{color:#999}.layui-colorpicker-main{position:absolute;z-index:66666666;width:280px;padding:7px;background:#FFF;border:1px solid #d2d2d2;border-radius:2px;box-shadow:0 2px 4px rgba(0,0,0,.12)}.layui-colorpicker-main-wrapper{height:180px;position:relative}.layui-colorpicker-basis{width:260px;height:100%;position:relative}.layui-colorpicker-basis-white{width:100%;height:100%;position:absolute;top:0;left:0;background:linear-gradient(90deg,#FFF,hsla(0,0%,100%,0))}.layui-colorpicker-basis-black{width:100%;height:100%;position:absolute;top:0;left:0;background:linear-gradient(0deg,#000,transparent)}.layui-colorpicker-basis-cursor{width:10px;height:10px;border:1px solid #FFF;border-radius:50%;position:absolute;top:-3px;right:-3px;cursor:pointer}.layui-colorpicker-side{position:absolute;top:0;right:0;width:12px;height:100%;background:linear-gradient(red,#FF0,#0F0,#0FF,#00F,#F0F,red)}.layui-colorpicker-side-slider{width:100%;height:5px;box-shadow:0 0 1px #888;box-sizing:border-box;background:#FFF;border-radius:1px;border:1px solid #f0f0f0;cursor:pointer;position:absolute;left:0}.layui-colorpicker-main-alpha{display:none;height:12px;margin-top:7px;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.layui-colorpicker-alpha-bgcolor{height:100%;position:relative}.layui-colorpicker-alpha-slider{width:5px;height:100%;box-shadow:0 0 1px #888;box-sizing:border-box;background:#FFF;border-radius:1px;border:1px solid #f0f0f0;cursor:pointer;position:absolute;top:0}.layui-colorpicker-main-pre{padding-top:7px;font-size:0}.layui-colorpicker-pre{width:20px;height:20px;border-radius:2px;display:inline-block;margin-left:6px;margin-bottom:7px;cursor:pointer}.layui-colorpicker-pre:nth-child(11n+1){margin-left:0}.layui-colorpicker-pre-isalpha{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.layui-colorpicker-pre.layui-this{box-shadow:0 0 3px 2px rgba(0,0,0,.15)}.layui-colorpicker-pre>div{height:100%;border-radius:2px}.layui-colorpicker-main-input{text-align:right;padding-top:7px}.layui-colorpicker-main-input .layui-btn-container .layui-btn{margin:0 0 0 10px}.layui-colorpicker-main-input div.layui-inline{float:left;margin-right:10px;font-size:14px}.layui-colorpicker-main-input input.layui-input{width:150px;height:30px;color:#666}.layui-slider{height:4px;background:#e2e2e2;border-radius:3px;position:relative;cursor:pointer}.layui-slider-bar{border-radius:3px;position:absolute;height:100%}.layui-slider-step{position:absolute;top:0;width:4px;height:4px;border-radius:50%;background:#FFF;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.layui-slider-wrap{width:36px;height:36px;position:absolute;top:-16px;-webkit-transform:translateX(-50%);transform:translateX(-50%);z-index:10;text-align:center}.layui-slider-wrap-btn{width:12px;height:12px;border-radius:50%;background:#FFF;display:inline-block;vertical-align:middle;cursor:pointer;transition:.3s}.layui-slider-wrap:after{content:"";height:100%;display:inline-block;vertical-align:middle}.layui-slider-wrap-btn.layui-slider-hover,.layui-slider-wrap-btn:hover{transform:scale(1.2)}.layui-slider-wrap-btn.layui-disabled:hover{transform:scale(1)!important}.layui-slider-tips{position:absolute;top:-42px;z-index:66666666;white-space:nowrap;display:none;-webkit-transform:translateX(-50%);transform:translateX(-50%);color:#FFF;background:#000;border-radius:3px;height:25px;line-height:25px;padding:0 10px}.layui-slider-tips:after{content:'';position:absolute;bottom:-12px;left:50%;margin-left:-6px;width:0;height:0;border-width:6px;border-style:solid;border-color:#000 transparent transparent}.layui-slider-input{width:70px;height:32px;border:1px solid #e6e6e6;border-radius:3px;font-size:16px;line-height:32px;position:absolute;right:0;top:-15px}.layui-slider-input-btn{display:none;position:absolute;top:0;right:0;width:20px;height:100%;border-left:1px solid #d2d2d2}.layui-slider-input-btn i{cursor:pointer;position:absolute;right:0;bottom:0;width:20px;height:50%;font-size:12px;line-height:16px;text-align:center;color:#999}.layui-slider-input-btn i:first-child{top:0;border-bottom:1px solid #d2d2d2}.layui-slider-input-txt{height:100%;font-size:14px}.layui-slider-input-txt input{height:100%;border:none}.layui-slider-input-btn i:hover{color:#009688}.layui-slider-vertical{width:4px;margin-left:34px}.layui-slider-vertical .layui-slider-bar{width:4px}.layui-slider-vertical .layui-slider-step{top:auto;left:0;-webkit-transform:translateY(50%);transform:translateY(50%)}.layui-slider-vertical .layui-slider-wrap{top:auto;left:-16px;-webkit-transform:translateY(50%);transform:translateY(50%)}.layui-slider-vertical .layui-slider-tips{top:auto;left:2px}@media \0screen{.layui-slider-wrap-btn{margin-left:-20px}.layui-slider-vertical .layui-slider-wrap-btn{margin-left:0;margin-bottom:-20px}.layui-slider-vertical .layui-slider-tips{margin-left:-8px}.layui-slider>span{margin-left:8px}}.layui-tree{line-height:22px}.layui-tree .layui-form-checkbox{margin:0!important}.layui-tree-set{width:100%;position:relative}.layui-tree-pack{display:none;padding-left:20px;position:relative}.layui-tree-iconClick,.layui-tree-main{display:inline-block;vertical-align:middle}.layui-tree-line .layui-tree-pack{padding-left:27px}.layui-tree-line .layui-tree-set .layui-tree-set:after{content:'';position:absolute;top:14px;left:-9px;width:17px;height:0;border-top:1px dotted #c0c4cc}.layui-tree-entry{position:relative;padding:3px 0;height:20px;white-space:nowrap}.layui-tree-entry:hover{background-color:#eee}.layui-tree-line .layui-tree-entry:hover{background-color:rgba(0,0,0,0)}.layui-tree-line .layui-tree-entry:hover .layui-tree-txt{color:#999;text-decoration:underline;transition:.3s}.layui-tree-main{cursor:pointer;padding-right:10px}.layui-tree-line .layui-tree-set:before{content:'';position:absolute;top:0;left:-9px;width:0;height:100%;border-left:1px dotted #c0c4cc}.layui-tree-line .layui-tree-set.layui-tree-setLineShort:before{height:13px}.layui-tree-line .layui-tree-set.layui-tree-setHide:before{height:0}.layui-tree-iconClick{position:relative;height:20px;line-height:20px;margin:0 10px;color:#c0c4cc}.layui-tree-icon{height:12px;line-height:12px;width:12px;text-align:center;border:1px solid #c0c4cc}.layui-tree-iconClick .layui-icon{font-size:18px}.layui-tree-icon .layui-icon{font-size:12px;color:#666}.layui-tree-iconArrow{padding:0 5px}.layui-tree-iconArrow:after{content:'';position:absolute;left:4px;top:3px;z-index:100;width:0;height:0;border-width:5px;border-style:solid;border-color:transparent transparent transparent #c0c4cc;transition:.5s}.layui-tree-btnGroup,.layui-tree-editInput{position:relative;vertical-align:middle;display:inline-block}.layui-tree-spread>.layui-tree-entry>.layui-tree-iconClick>.layui-tree-iconArrow:after{transform:rotate(90deg) translate(3px,4px)}.layui-tree-txt{display:inline-block;vertical-align:middle;color:#555}.layui-tree-search{margin-bottom:15px;color:#666}.layui-tree-btnGroup .layui-icon{display:inline-block;vertical-align:middle;padding:0 2px;cursor:pointer}.layui-tree-btnGroup .layui-icon:hover{color:#999;transition:.3s}.layui-tree-entry:hover .layui-tree-btnGroup{visibility:visible}.layui-tree-editInput{height:20px;line-height:20px;padding:0 3px;border:none;background-color:rgba(0,0,0,.05)}.layui-tree-emptyText{text-align:center;color:#999}.layui-anim{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.layui-anim.layui-icon{display:inline-block}.layui-anim-loop{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.layui-trans,.layui-trans a{transition:all .3s;-webkit-transition:all .3s}@-webkit-keyframes layui-rotate{from{-webkit-transform:rotate(0)}to{-webkit-transform:rotate(360deg)}}@keyframes layui-rotate{from{transform:rotate(0)}to{transform:rotate(360deg)}}.layui-anim-rotate{-webkit-animation-name:layui-rotate;animation-name:layui-rotate;-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-timing-function:linear;animation-timing-function:linear}@-webkit-keyframes layui-up{from{-webkit-transform:translate3d(0,100%,0);opacity:.3}to{-webkit-transform:translate3d(0,0,0);opacity:1}}@keyframes layui-up{from{transform:translate3d(0,100%,0);opacity:.3}to{transform:translate3d(0,0,0);opacity:1}}.layui-anim-up{-webkit-animation-name:layui-up;animation-name:layui-up}@-webkit-keyframes layui-upbit{from{-webkit-transform:translate3d(0,30px,0);opacity:.3}to{-webkit-transform:translate3d(0,0,0);opacity:1}}@keyframes layui-upbit{from{transform:translate3d(0,30px,0);opacity:.3}to{transform:translate3d(0,0,0);opacity:1}}.layui-anim-upbit{-webkit-animation-name:layui-upbit;animation-name:layui-upbit}@-webkit-keyframes layui-scale{0%{opacity:.3;-webkit-transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1)}}@keyframes layui-scale{0%{opacity:.3;-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-ms-transform:scale(1);transform:scale(1)}}.layui-anim-scale{-webkit-animation-name:layui-scale;animation-name:layui-scale}@-webkit-keyframes layui-scale-spring{0%{opacity:.5;-webkit-transform:scale(.5)}80%{opacity:.8;-webkit-transform:scale(1.1)}100%{opacity:1;-webkit-transform:scale(1)}}@keyframes layui-scale-spring{0%{opacity:.5;transform:scale(.5)}80%{opacity:.8;transform:scale(1.1)}100%{opacity:1;transform:scale(1)}}.layui-anim-scaleSpring{-webkit-animation-name:layui-scale-spring;animation-name:layui-scale-spring}@-webkit-keyframes layui-fadein{0%{opacity:0}100%{opacity:1}}@keyframes layui-fadein{0%{opacity:0}100%{opacity:1}}.layui-anim-fadein{-webkit-animation-name:layui-fadein;animation-name:layui-fadein}@-webkit-keyframes layui-fadeout{0%{opacity:1}100%{opacity:0}}@keyframes layui-fadeout{0%{opacity:1}100%{opacity:0}}.layui-anim-fadeout{-webkit-animation-name:layui-fadeout;animation-name:layui-fadeout}
\ No newline at end of file
diff --git a/static/assets/css/layui.mobile.css b/static/assets/css/layui.mobile.css
new file mode 100644
index 0000000..7835392
--- /dev/null
+++ b/static/assets/css/layui.mobile.css
@@ -0,0 +1,2 @@
+/** layui-v2.5.6 MIT License By https://www.layui.com */
+ blockquote,body,button,dd,div,dl,dt,form,h1,h2,h3,h4,h5,h6,input,legend,li,ol,p,td,textarea,th,ul{margin:0;padding:0;-webkit-tap-highlight-color:rgba(0,0,0,0)}html{font:12px 'Helvetica Neue','PingFang SC',STHeitiSC-Light,Helvetica,Arial,sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}a,button,input{-webkit-tap-highlight-color:rgba(255,0,0,0)}a{text-decoration:none;background:0 0}a:active,a:hover{outline:0}table{border-collapse:collapse;border-spacing:0}li{list-style:none}b,strong{font-weight:700}h1,h2,h3,h4,h5,h6{font-weight:500}address,cite,dfn,em,var{font-style:normal}dfn{font-style:italic}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}img{border:0;vertical-align:bottom}.layui-inline,input,label{vertical-align:middle}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0;outline:0}button,select{text-transform:none}select{-webkit-appearance:none;border:none}input{line-height:normal}input[type=checkbox],input[type=radio]{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-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}@font-face{font-family:layui-icon;src:url(../font/iconfont.eot?v=1.0.7);src:url(../font/iconfont.eot?v=1.0.7#iefix) format('embedded-opentype'),url(../font/iconfont.woff?v=1.0.7) format('woff'),url(../font/iconfont.ttf?v=1.0.7) format('truetype'),url(../font/iconfont.svg?v=1.0.7#iconfont) format('svg')}.layui-icon{font-family:layui-icon!important;font-size:16px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.layui-box,.layui-box *{-webkit-box-sizing:content-box!important;-moz-box-sizing:content-box!important;box-sizing:content-box!important}.layui-border-box,.layui-border-box *{-webkit-box-sizing:border-box!important;-moz-box-sizing:border-box!important;box-sizing:border-box!important}.layui-inline{position:relative;display:inline-block;*display:inline;*zoom:1}.layui-edge,.layui-upload-iframe{position:absolute;width:0;height:0}.layui-edge{border-style:dashed;border-color:transparent;overflow:hidden}.layui-elip{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-unselect{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.layui-disabled,.layui-disabled:active{background-color:#d2d2d2!important;color:#fff!important;cursor:not-allowed!important}.layui-circle{border-radius:100%}.layui-show{display:block!important}.layui-hide{display:none!important}.layui-upload-iframe{border:0;visibility:hidden}.layui-upload-enter{border:1px solid #009E94;background-color:#009E94;color:#fff;-webkit-transform:scale(1.1);transform:scale(1.1)}@-webkit-keyframes layui-m-anim-scale{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes layui-m-anim-scale{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}.layui-m-anim-scale{animation-name:layui-m-anim-scale;-webkit-animation-name:layui-m-anim-scale}@-webkit-keyframes layui-m-anim-up{0%{opacity:0;-webkit-transform:translateY(800px);transform:translateY(800px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes layui-m-anim-up{0%{opacity:0;-webkit-transform:translateY(800px);transform:translateY(800px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}.layui-m-anim-up{-webkit-animation-name:layui-m-anim-up;animation-name:layui-m-anim-up}@-webkit-keyframes layui-m-anim-left{0%{-webkit-transform:translateX(100%);transform:translateX(100%)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes layui-m-anim-left{0%{-webkit-transform:translateX(100%);transform:translateX(100%)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}.layui-m-anim-left{-webkit-animation-name:layui-m-anim-left;animation-name:layui-m-anim-left}@-webkit-keyframes layui-m-anim-right{0%{-webkit-transform:translateX(-100%);transform:translateX(-100%)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes layui-m-anim-right{0%{-webkit-transform:translateX(-100%);transform:translateX(-100%)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}.layui-m-anim-right{-webkit-animation-name:layui-m-anim-right;animation-name:layui-m-anim-right}@-webkit-keyframes layui-m-anim-lout{0%{-webkit-transform:translateX(0);transform:translateX(0)}100%{-webkit-transform:translateX(-100%);transform:translateX(-100%)}}@keyframes layui-m-anim-lout{0%{-webkit-transform:translateX(0);transform:translateX(0)}100%{-webkit-transform:translateX(-100%);transform:translateX(-100%)}}.layui-m-anim-lout{-webkit-animation-name:layui-m-anim-lout;animation-name:layui-m-anim-lout}@-webkit-keyframes layui-m-anim-rout{0%{-webkit-transform:translateX(0);transform:translateX(0)}100%{-webkit-transform:translateX(100%);transform:translateX(100%)}}@keyframes layui-m-anim-rout{0%{-webkit-transform:translateX(0);transform:translateX(0)}100%{-webkit-transform:translateX(100%);transform:translateX(100%)}}.layui-m-anim-rout{-webkit-animation-name:layui-m-anim-rout;animation-name:layui-m-anim-rout}.layui-m-layer{position:relative;z-index:19891014}.layui-m-layer *{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.layui-m-layermain,.layui-m-layershade{position:fixed;left:0;top:0;width:100%;height:100%}.layui-m-layershade{background-color:rgba(0,0,0,.7);pointer-events:auto}.layui-m-layermain{display:table;font-family:Helvetica,arial,sans-serif;pointer-events:none}.layui-m-layermain .layui-m-layersection{display:table-cell;vertical-align:middle;text-align:center}.layui-m-layerchild{position:relative;display:inline-block;text-align:left;background-color:#fff;font-size:14px;border-radius:5px;box-shadow:0 0 8px rgba(0,0,0,.1);pointer-events:auto;-webkit-overflow-scrolling:touch;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.2s;animation-duration:.2s}.layui-m-layer0 .layui-m-layerchild{width:90%;max-width:640px}.layui-m-layer1 .layui-m-layerchild{border:none;border-radius:0}.layui-m-layer2 .layui-m-layerchild{width:auto;max-width:260px;min-width:40px;border:none;background:0 0;box-shadow:none;color:#fff}.layui-m-layerchild h3{padding:0 10px;height:60px;line-height:60px;font-size:16px;font-weight:400;border-radius:5px 5px 0 0;text-align:center}.layui-m-layerbtn span,.layui-m-layerchild h3{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-m-layercont{padding:50px 30px;line-height:22px;text-align:center}.layui-m-layer1 .layui-m-layercont{padding:0;text-align:left}.layui-m-layer2 .layui-m-layercont{text-align:center;padding:0;line-height:0}.layui-m-layer2 .layui-m-layercont i{width:25px;height:25px;margin-left:8px;display:inline-block;background-color:#fff;border-radius:100%;-webkit-animation:layui-m-anim-loading 1.4s infinite ease-in-out;animation:layui-m-anim-loading 1.4s infinite ease-in-out;-webkit-animation-fill-mode:both;animation-fill-mode:both}.layui-m-layerbtn,.layui-m-layerbtn span{position:relative;text-align:center;border-radius:0 0 5px 5px}.layui-m-layer2 .layui-m-layercont p{margin-top:20px}@-webkit-keyframes layui-m-anim-loading{0%,100%,80%{transform:scale(0);-webkit-transform:scale(0)}40%{transform:scale(1);-webkit-transform:scale(1)}}@keyframes layui-m-anim-loading{0%,100%,80%{transform:scale(0);-webkit-transform:scale(0)}40%{transform:scale(1);-webkit-transform:scale(1)}}.layui-m-layer2 .layui-m-layercont i:first-child{margin-left:0;-webkit-animation-delay:-.32s;animation-delay:-.32s}.layui-m-layer2 .layui-m-layercont i.layui-m-layerload{-webkit-animation-delay:-.16s;animation-delay:-.16s}.layui-m-layer2 .layui-m-layercont>div{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/static/assets/css/login.css b/static/assets/css/login.css
new file mode 100644
index 0000000..f9dc538
--- /dev/null
+++ b/static/assets/css/login.css
@@ -0,0 +1,163 @@
+html,body{
+ height: 100%;
+}
+body{
+ background-color: #f0f2f5;
+}
+
+@font-face {font-family: "AI";
+ src: url('../font/ai.eot?t=1522660080732'); /* IE9*/
+ src: url('../font/ai.eot?t=1522660080732#iefix') format('embedded-opentype'), /* IE6-IE8 */
+ url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAY8AAsAAAAACOwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFZW7klTY21hcAAAAYAAAABxAAABsgVg1KRnbHlmAAAB9AAAAikAAALAJwyXdWhlYWQAAAQgAAAALwAAADYQ72wdaGhlYQAABFAAAAAcAAAAJAfeA4ZobXR4AAAEbAAAABMAAAAUE+kAAGxvY2EAAASAAAAADAAAAAwBgAIWbWF4cAAABIwAAAAeAAAAIAEUAF1uYW1lAAAErAAAAUgAAAIlgV2vXHBvc3QAAAX0AAAARgAAAFxjcyq+eJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2Bk/s04gYGVgYOpk+kMAwNDP4RmfM1gxMjBwMDEwMrMgBUEpLmmMDgwVDxPY27438AQw9zA0AAUZgTJAQAr+wzWeJzFkcENgCAQBOdAjTGW4tu31fjy5YvyrAbL0IXzoRW4lyF7myMQAFogikk0YDtG0abUah4Zat6wqB/oCaqU53yc63Upe3uXac6r+Ki9QabjN9l/R3811nV5Or046UFXzLNTfiQfTpk5V4dwAxJQGNAAAAB4nFWQP2/TQBjG773L2YkvsVP/TZzYiWMSg0qNSN0EBCQMLEUMIBY6EOgHgIGlqsSQpRUDA0tGGBASc6cuHYpUqUjN0m8AhYlOHWByXM4ulYr1+rnn3nul+92DKEKn38kOqSANXUbX0T30ECEQ5qElYwe8IArxPBgeNSxdJoEfeKLfCskdsFqCbnZ7UccSREEBGVxY9Lq9IMQBLEUDfAu6pgNQrdmP1XZdJe9AqgTuRnIffwSj4deVwUKyfHWod5tafq2oqlVVfZsXKM1jnFNkeGGZBVqQhOQTVWxjp3EFN6BYDewHK6VmTV19E7102lYBYDwGrdaUPw/n7Dler21TU6tiuZSv2CX/kg5rP1lFKzqdH4h/hL91l+ySMWLIQs30nUg0kdVD/Q4iIQQD6LtgyUAsz/BEqx/At2lyQiko0ykolCYn063jXO54K9MPk+QGfJ0sHB2RcXp0YTTeOB/iih9N7qZTKMfvPyVfOEZ6v48ihDQvzdD30jRppotZh1zw7TTna9AfQAgKCLq1Sm4rhqHEe1zJ8uwg3eAlrqV4P/XkJteZxRxDej5iYLjSepHhbcM1eP0+W5LNs/VQ4sejJ8w1QHrFXJbmlMvC+o8TvBCiHucxdYFmKmYd7YJvC61ONIQghAE0wNRF8j7eK+t6OcONtzNEZXbAW3KGqMT73ONfzDHZs6cc1GHrjIOC3tB5/eE/pD7ZPHeHkllnoxXJMf/R/gVcdIfdAAAAeJxjYGRgYADisxEb+eL5bb4ycLMwgMC1F8IfEPT/AywMzA1ALgcDE0gUAEFcC2cAeJxjYGRgYG7438AQw8IAAkCSkQEVsAIARwsCbnicY2FgYGB+ycDAwoDAAA6bAP0AAAAAAAB2ALYBCgFgeJxjYGRgYGBlCARiEGACYi4gZGD4D+YzAAARLQFyAAB4nF2RPU7DQBCFn0MShCNRgIAOLRQUIOwkZTorUiK3KVLQJc46P7K91mYTKSeh4AQUFJyCgjtwFl6cCQW2dvTNmzczKxvABX7g4fBc8RzYQ43ZgWs4xY3wCbNb4TpZCTfQwr1wk/qzsI8nhMItXOKFE7z6GbNH5MIeJ70K13CON+ET6u/Cdb4fwg1c41O4Sf1L2McY38ItPHh3ft/qidMzNd2pZWKK1BTOj+KRnm+yiY3iKB5ru16aQnWCdhQPdaHt0b/ezrvOpSq1JlcDNuosM6q0ZqUTFyycK3thmIoeJCbn+j4sNCZwjDN+mil2jEskMCiQVtHRFyHGiJ45Nsjot5WyP2OqFmv27L0KHQRoV5UhK0VV/T9/jS0ndak67lA8lt05aSAbNbdkZIWyqq2oJNQDLKquEj3+pPDvhkd/UN08/wU7iFeyeJxjYGKAAC4G7ICVkYmRmZGFkZWRjYGxQiyxqCi/XLcoMz2jRDc5syg5J1W3WDefIzc1rzQtPyeFC8QozQMxGRgAmgAQtAAA') format('woff'),
+ url('../font/ai.ttf?t=1522660080732') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
+ url('../font/ai.svg?t=1522660080732#AI') format('svg'); /* iOS 4.1- */
+}
+
+.ai {
+ font-family:"AI" !important;
+ font-size:16px;
+ font-style:normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.ai-enter:before { content: "\e766"; }
+
+.login-wrap{
+ display: table;
+ width: 100%;
+}
+
+.login-container{
+ width: 100%;
+ display: table-cell;
+ vertical-align: middle;
+}
+
+.login-form{
+ width: 320px;
+ padding: 40px 30px;
+ margin: 0 auto;
+ background: #fff;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+.login-form .input-group{
+ position: relative;
+ width: 100%;
+ padding: 10px;
+ vertical-align: top;
+ box-sizing:border-box;
+}
+.login-form .input-group .input-field{
+ position: relative;
+ width: 100%;
+ margin-top: 10px;
+ padding: 10px 3px;
+ color: #555;
+ font-size: 15px;
+ display: block;
+ border:none;
+ z-index: 1;
+ background-color: transparent;
+ -webkit-appearance: none;
+ box-sizing:border-box;
+}
+
+.login-form .input-group .input-label{
+ position: absolute;
+ width: 100%;
+ bottom: 0;
+ left: 0;
+ padding: 0 5px;
+ font-size: 14px;
+ margin-bottom: 0;
+ text-align: left;
+ cursor: text;
+ display: inline-block;
+ box-sizing:border-box;
+}
+
+.login-form .input-group .input-label > .label-title{
+ padding: 17px 8px;
+ color: #5d6779;
+ display: block;
+}
+
+.login-form .input-group .input-label:before{
+ position: absolute;
+ content:'';
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: calc(100% - 10px);
+ border-bottom:1px solid #e5e5e5;
+}
+
+.login-form .input-group .input-field:focus {
+ outline: none;
+}
+.login-form .input-group .input-field:focus + .input-label > .label-title,
+.input-group.field-focus .input-label > .label-title {
+ -webkit-animation: fieldUp 0.3s forwards;
+ animation: fieldUp 0.3s forwards;
+ font-size: 12px;
+ color: #ccc;
+}
+
+.login-button{
+ position: relative;
+ margin-top: 20px;
+ display: block;
+ width: 100%;
+ padding:8px;
+ background-color: #29adeb;
+ background-repeat: repeat-y;
+ background-image: -moz-linear-gradient(left,#29adeb,#177ce3);
+ background-image: -webkit-linear-gradient(left,#29adeb,#177ce3);
+ background-image: -o-linear-gradient(left,#29adeb,#177ce3);
+ background-image: linear-gradient(left,#29adeb,#177ce3);
+ box-shadow: 0px 7px 10px 0px rgba(23, 124, 227, 0.25);
+ text-align: center;
+ border-radius: 3px;
+ color: #fff;
+ border:none;
+ cursor: pointer;
+ transition: padding-right .4s ease;
+}
+
+.login-button i{
+ position: absolute;
+ top: 8px;
+ font-size: 20px;
+ margin-left: 5px;
+ opacity: 0;
+ transition: opacity .4s ease;
+}
+
+.login-button:hover{
+ padding-right: 30px;
+}
+.login-button:hover i{
+ opacity: .9;
+}
+
+.login-button:focus{
+ outline: none;
+}
+
+@-webkit-keyframes fieldUp {
+ 50% {
+ opacity: 0;
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: translateY(-50%);
+ transform: translateY(-50%);
+ }
+}
\ No newline at end of file
diff --git a/static/assets/css/modules/code.css b/static/assets/css/modules/code.css
new file mode 100644
index 0000000..9143a25
--- /dev/null
+++ b/static/assets/css/modules/code.css
@@ -0,0 +1,2 @@
+/** layui-v2.5.6 MIT License By https://www.layui.com */
+ html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #e2e2e2;border-left-width:6px;background-color:#F2F2F2;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:32px;line-height:32px;border-bottom:1px solid #e2e2e2}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 5px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none}
\ No newline at end of file
diff --git a/static/assets/css/modules/laydate/default/laydate.css b/static/assets/css/modules/laydate/default/laydate.css
new file mode 100644
index 0000000..b900971
--- /dev/null
+++ b/static/assets/css/modules/laydate/default/laydate.css
@@ -0,0 +1,2 @@
+/** layui-v2.5.6 MIT License By https://www.layui.com */
+ .laydate-set-ym,.layui-laydate,.layui-laydate *,.layui-laydate-list{box-sizing:border-box}html #layuicss-laydate{display:none;position:absolute;width:1989px}.layui-laydate *{margin:0;padding:0}.layui-laydate{position:absolute;z-index:66666666;margin:5px 0;border-radius:2px;font-size:14px;-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-name:laydate-upbit;animation-name:laydate-upbit}.layui-laydate-main{width:272px}.layui-laydate-content td,.layui-laydate-header *,.layui-laydate-list li{transition-duration:.3s;-webkit-transition-duration:.3s}@-webkit-keyframes laydate-upbit{from{-webkit-transform:translate3d(0,20px,0);opacity:.3}to{-webkit-transform:translate3d(0,0,0);opacity:1}}@keyframes laydate-upbit{from{transform:translate3d(0,20px,0);opacity:.3}to{transform:translate3d(0,0,0);opacity:1}}.layui-laydate-static{position:relative;z-index:0;display:inline-block;margin:0;-webkit-animation:none;animation:none}.laydate-ym-show .laydate-next-m,.laydate-ym-show .laydate-prev-m{display:none!important}.laydate-ym-show .laydate-next-y,.laydate-ym-show .laydate-prev-y{display:inline-block!important}.laydate-time-show .laydate-set-ym span[lay-type=month],.laydate-time-show .laydate-set-ym span[lay-type=year],.laydate-time-show .layui-laydate-header .layui-icon,.laydate-ym-show .laydate-set-ym span[lay-type=month]{display:none!important}.layui-laydate-header{position:relative;line-height:30px;padding:10px 70px 5px}.laydate-set-ym span,.layui-laydate-header i{padding:0 5px;cursor:pointer}.layui-laydate-header *{display:inline-block;vertical-align:bottom}.layui-laydate-header i{position:absolute;top:10px;color:#999;font-size:18px}.layui-laydate-header i.laydate-prev-y{left:15px}.layui-laydate-header i.laydate-prev-m{left:45px}.layui-laydate-header i.laydate-next-y{right:15px}.layui-laydate-header i.laydate-next-m{right:45px}.laydate-set-ym{width:100%;text-align:center;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.laydate-time-text{cursor:default!important}.layui-laydate-content{position:relative;padding:10px;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.layui-laydate-content table{border-collapse:collapse;border-spacing:0}.layui-laydate-content td,.layui-laydate-content th{width:36px;height:30px;padding:5px;text-align:center}.layui-laydate-content td{position:relative;cursor:pointer}.laydate-day-mark{position:absolute;left:0;top:0;width:100%;height:100%;line-height:30px;font-size:12px;overflow:hidden}.laydate-day-mark::after{position:absolute;content:'';right:2px;top:2px;width:5px;height:5px;border-radius:50%}.layui-laydate-footer{position:relative;height:46px;line-height:26px;padding:10px 20px}.layui-laydate-footer span{margin-right:15px;display:inline-block;cursor:pointer;font-size:12px}.layui-laydate-footer span:hover{color:#5FB878}.laydate-footer-btns{position:absolute;right:10px;top:10px}.laydate-footer-btns span{height:26px;line-height:26px;margin:0 0 0 -1px;padding:0 10px;border:1px solid #C9C9C9;background-color:#fff;white-space:nowrap;vertical-align:top;border-radius:2px}.layui-laydate-list>li,.layui-laydate-range .layui-laydate-main{display:inline-block;vertical-align:middle}.layui-laydate-list{position:absolute;left:0;top:0;width:100%;height:100%;padding:10px;background-color:#fff}.layui-laydate-list>li{position:relative;width:33.3%;height:36px;line-height:36px;margin:3px 0;text-align:center;cursor:pointer}.laydate-month-list>li{width:25%;margin:17px 0}.laydate-time-list>li{height:100%;margin:0;line-height:normal;cursor:default}.laydate-time-list p{position:relative;top:-4px;line-height:29px}.laydate-time-list ol{height:181px;overflow:hidden}.laydate-time-list>li:hover ol{overflow-y:auto}.laydate-time-list ol li{width:130%;padding-left:33px;line-height:30px;text-align:left;cursor:pointer}.layui-laydate-hint{position:absolute;top:115px;left:50%;width:250px;margin-left:-125px;line-height:20px;padding:15px;text-align:center;font-size:12px}.layui-laydate-range{width:546px}.layui-laydate-range .laydate-main-list-0 .laydate-next-m,.layui-laydate-range .laydate-main-list-0 .laydate-next-y,.layui-laydate-range .laydate-main-list-1 .laydate-prev-m,.layui-laydate-range .laydate-main-list-1 .laydate-prev-y{display:none}.layui-laydate-range .laydate-main-list-1 .layui-laydate-content{border-left:1px solid #e2e2e2}.layui-laydate,.layui-laydate-hint{border:1px solid #d2d2d2;box-shadow:0 2px 4px rgba(0,0,0,.12);background-color:#fff;color:#666}.layui-laydate-header{border-bottom:1px solid #e2e2e2}.layui-laydate-header i:hover,.layui-laydate-header span:hover{color:#5FB878}.layui-laydate-content{border-top:none 0;border-bottom:none 0}.layui-laydate-content th{font-weight:400;color:#333}.layui-laydate-content td{color:#666}.layui-laydate-content td.laydate-selected{background-color:#00F7DE}.laydate-selected:hover{background-color:#00F7DE!important}.layui-laydate-content td:hover,.layui-laydate-list li:hover{background-color:#eaeaea;color:#333}.laydate-time-list li ol{margin:0;padding:0;border:1px solid #e2e2e2;border-left-width:0}.laydate-time-list li:first-child ol{border-left-width:1px}.laydate-time-list>li:hover{background:0 0}.layui-laydate-content .laydate-day-next,.layui-laydate-content .laydate-day-prev{color:#d2d2d2}.laydate-selected.laydate-day-next,.laydate-selected.laydate-day-prev{background-color:#f8f8f8!important}.layui-laydate-footer{border-top:1px solid #e2e2e2}.layui-laydate-hint{color:#FF5722}.laydate-day-mark::after{background-color:#5FB878}.layui-laydate-content td.layui-this .laydate-day-mark::after{display:none}.layui-laydate-footer span[lay-type=date]{color:#5FB878}.layui-laydate .layui-this{background-color:#009688!important;color:#fff!important}.layui-laydate .laydate-disabled,.layui-laydate .laydate-disabled:hover{background:0 0!important;color:#d2d2d2!important;cursor:not-allowed!important;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.laydate-theme-molv{border:none}.laydate-theme-molv.layui-laydate-range{width:548px}.laydate-theme-molv .layui-laydate-main{width:274px}.laydate-theme-molv .layui-laydate-header{border:none;background-color:#009688}.laydate-theme-molv .layui-laydate-header i,.laydate-theme-molv .layui-laydate-header span{color:#f6f6f6}.laydate-theme-molv .layui-laydate-header i:hover,.laydate-theme-molv .layui-laydate-header span:hover{color:#fff}.laydate-theme-molv .layui-laydate-content{border:1px solid #e2e2e2;border-top:none;border-bottom:none}.laydate-theme-molv .laydate-main-list-1 .layui-laydate-content{border-left:none}.laydate-theme-grid .laydate-month-list>li,.laydate-theme-grid .laydate-year-list>li,.laydate-theme-grid .layui-laydate-content td,.laydate-theme-grid .layui-laydate-content thead,.laydate-theme-molv .layui-laydate-footer{border:1px solid #e2e2e2}.laydate-theme-grid .laydate-selected,.laydate-theme-grid .laydate-selected:hover{background-color:#f2f2f2!important;color:#009688!important}.laydate-theme-grid .laydate-selected.laydate-day-next,.laydate-theme-grid .laydate-selected.laydate-day-prev{color:#d2d2d2!important}.laydate-theme-grid .laydate-month-list,.laydate-theme-grid .laydate-year-list{margin:1px 0 0 1px}.laydate-theme-grid .laydate-month-list>li,.laydate-theme-grid .laydate-year-list>li{margin:0 -1px -1px 0}.laydate-theme-grid .laydate-year-list>li{height:43px;line-height:43px}.laydate-theme-grid .laydate-month-list>li{height:71px;line-height:71px}
\ No newline at end of file
diff --git a/static/assets/css/modules/layer/default/icon-ext.png b/static/assets/css/modules/layer/default/icon-ext.png
new file mode 100644
index 0000000..bbbb669
Binary files /dev/null and b/static/assets/css/modules/layer/default/icon-ext.png differ
diff --git a/static/assets/css/modules/layer/default/icon.png b/static/assets/css/modules/layer/default/icon.png
new file mode 100644
index 0000000..3e17da8
Binary files /dev/null and b/static/assets/css/modules/layer/default/icon.png differ
diff --git a/static/assets/css/modules/layer/default/layer.css b/static/assets/css/modules/layer/default/layer.css
new file mode 100644
index 0000000..032ae12
--- /dev/null
+++ b/static/assets/css/modules/layer/default/layer.css
@@ -0,0 +1,2 @@
+/** layui-v2.5.6 MIT License By https://www.layui.com */
+ .layui-layer-imgbar,.layui-layer-imgtit a,.layui-layer-tab .layui-layer-title span,.layui-layer-title{text-overflow:ellipsis;white-space:nowrap}html #layuicss-layer{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;border-radius:2px;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}.layer-anim{-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.3s;animation-duration:.3s}@-webkit-keyframes layer-bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes layer-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-00{-webkit-animation-name:layer-bounceIn;animation-name:layer-bounceIn}@-webkit-keyframes layer-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 layer-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:layer-zoomInDown;animation-name:layer-zoomInDown}@-webkit-keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes layer-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:layer-fadeInUpBig;animation-name:layer-fadeInUpBig}@-webkit-keyframes layer-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 layer-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:layer-zoomInLeft;animation-name:layer-zoomInLeft}@-webkit-keyframes layer-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 layer-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:layer-rollIn;animation-name:layer-rollIn}@keyframes layer-fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:layer-fadeIn;animation-name:layer-fadeIn}@-webkit-keyframes layer-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 layer-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:layer-shake;animation-name:layer-shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.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:1px -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 15px 12px;pointer-events:auto;user-select:none;-webkit-user-select:none}.layui-layer-btn a{height:28px;line-height:28px;margin:5px 5px 0;padding:0 15px;border:1px solid #dedede;background-color:#fff;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:#1E9FFF;background-color:#1E9FFF;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:8px 15px;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:5px;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:5px 10px 10px;text-align:right;border-top:1px solid #E9E7E7}.layui-layer-lan .layui-layer-btn a{background:#fff;border-color:#E9E7E7;color:#333}.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;border-color:#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:230px;height:36px;margin:0 auto;line-height:30px;padding-left:10px;border:1px solid #e6e6e6;color:#333}.layui-layer-prompt textarea.layui-layer-input{width:300px;height:100px;line-height:20px;padding:6px 10px}.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;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;overflow:hidden;cursor:pointer}.layui-layer-tab .layui-layer-title span.layui-this{height:43px;border-left:1px solid #eee;border-right:1px solid #eee;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.layui-this{display:block}.layui-layer-photos{-webkit-animation-duration:.8s;animation-duration:.8s}.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}@-webkit-keyframes layer-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 layer-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:layer-bounceOut;animation-name:layer-bounceOut;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.2s;animation-duration:.2s}@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/static/assets/css/modules/layer/default/loading-0.gif b/static/assets/css/modules/layer/default/loading-0.gif
new file mode 100644
index 0000000..6f3c953
Binary files /dev/null and b/static/assets/css/modules/layer/default/loading-0.gif differ
diff --git a/static/assets/css/modules/layer/default/loading-1.gif b/static/assets/css/modules/layer/default/loading-1.gif
new file mode 100644
index 0000000..db3a483
Binary files /dev/null and b/static/assets/css/modules/layer/default/loading-1.gif differ
diff --git a/static/assets/css/modules/layer/default/loading-2.gif b/static/assets/css/modules/layer/default/loading-2.gif
new file mode 100644
index 0000000..5bb90fd
Binary files /dev/null and b/static/assets/css/modules/layer/default/loading-2.gif differ
diff --git a/static/assets/css/view.css b/static/assets/css/view.css
new file mode 100644
index 0000000..43debf7
--- /dev/null
+++ b/static/assets/css/view.css
@@ -0,0 +1,136 @@
+.layui-view-body{
+ background-color: #f0f2f5;
+}
+
+.layui-content{
+ padding: 20px;
+}
+
+.layui-tab-title{
+ border-bottom-color: #e8e8e8;
+}
+.layui-card .layui-tab-brief .layui-tab-title li{
+ margin:0 15px;
+ padding: 0;
+}
+
+.layui-form-checked i, .layui-form-checked:hover i,
+.layui-form-radio>i:hover, .layui-form-radioed>i,
+.layui-breadcrumb a:hover,
+.layui-laypage a:hover,
+.layui-tab-brief>.layui-tab-title .layui-this{
+ color: #177ce3!important;
+}
+
+.layui-btn-primary:hover,
+.layui-form-onswitch,
+.layui-form-checked[lay-skin=primary] i,
+.layui-form-checkbox[lay-skin=primary]:hover i,
+.layui-form-checked, .layui-form-checked:hover,
+.layui-tab-brief>.layui-tab-more li.layui-this:after,
+.layui-tab-brief>.layui-tab-title .layui-this:after{
+ border-color: #177ce3;
+}
+
+.layui-checkbox-disbaled[lay-skin=primary]:hover i {
+ border-color: #d2d2d2!important;
+}
+
+.layui-form-onswitch,
+.layui-form-checked[lay-skin=primary] i,
+.layui-form-select dl dd.layui-this,
+.layui-laypage .layui-laypage-curr .layui-laypage-em,
+.layui-form-checked span, .layui-form-checked:hover span{
+ background-color: #177ce3;
+}
+.layui-btn-blue{
+ background-color: #177ce3;
+ background-repeat: repeat-y;
+ background-image: -moz-linear-gradient(left,#29adeb,#177ce3);
+ background-image: -webkit-linear-gradient(left,#29adeb,#177ce3);
+ background-image: -o-linear-gradient(left,#29adeb,#177ce3);
+ background-image: linear-gradient(left,#29adeb,#177ce3);
+}
+
+.layui-form-checkbox[lay-skin=primary]:hover span{
+ background: 0 0!important;
+}
+
+.layui-page-header{
+ margin: -20px -20px 20px;
+}
+
+.layui-page-header .pagewrap{
+ padding: 15px 20px;
+ background-color: #fff;
+}
+
+.layui-page-header .title{
+ margin-top: 15px;
+}
+
+.chart-card{
+ padding: 20px 24px 8px;
+}
+
+.chart-card .chart-header{
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+}
+
+.chart-card .metawrap{
+ float: left;
+}
+
+.chart-card .metawrap .meta{
+ color: rgba(0,0,0,.45);
+ font-size: 14px;
+ line-height: 22px;
+ height: 22px;
+}
+
+.chart-card .metawrap .total{
+ overflow: hidden;
+ text-overflow: ellipsis;
+ word-break: break-all;
+ white-space: nowrap;
+ color: rgba(0,0,0,.85);
+ margin-top: 4px;
+ margin-bottom: 0;
+ font-size: 30px;
+ line-height: 38px;
+ height: 38px;
+}
+
+.chart-card .chart-body{
+ margin-bottom: 12px;
+ position: relative;
+ width: 100%;
+}
+
+.chart-card .chart-footer{
+ padding-top: 9px;
+ margin-top: 8px;
+ border-top: 1px solid #e8e8e8;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+.chart-card .field{
+
+}
+
+.chart-card .field span{
+ font-size: 14px;
+ line-height: 22px;
+}
+
+.chart-card .field span:last-child{
+ margin-left: 8px;
+ color: rgba(0,0,0,.85);
+}
+
+.form-box{
+ padding: 10px 0;
+}
\ No newline at end of file
diff --git a/static/assets/font/ai.eot b/static/assets/font/ai.eot
new file mode 100644
index 0000000..75a6d48
Binary files /dev/null and b/static/assets/font/ai.eot differ
diff --git a/static/assets/font/ai.svg b/static/assets/font/ai.svg
new file mode 100644
index 0000000..44923f1
--- /dev/null
+++ b/static/assets/font/ai.svg
@@ -0,0 +1,42 @@
+
+
+
+
diff --git a/static/assets/font/ai.ttf b/static/assets/font/ai.ttf
new file mode 100644
index 0000000..7555c36
Binary files /dev/null and b/static/assets/font/ai.ttf differ
diff --git a/static/assets/font/ai.woff b/static/assets/font/ai.woff
new file mode 100644
index 0000000..658fef1
Binary files /dev/null and b/static/assets/font/ai.woff differ
diff --git a/static/assets/font/iconfont.eot b/static/assets/font/iconfont.eot
new file mode 100644
index 0000000..622d7ec
Binary files /dev/null and b/static/assets/font/iconfont.eot differ
diff --git a/static/assets/font/iconfont.svg b/static/assets/font/iconfont.svg
new file mode 100644
index 0000000..999ca1f
--- /dev/null
+++ b/static/assets/font/iconfont.svg
@@ -0,0 +1,554 @@
+
+
+
+
diff --git a/static/assets/font/iconfont.ttf b/static/assets/font/iconfont.ttf
new file mode 100644
index 0000000..06e30f9
Binary files /dev/null and b/static/assets/font/iconfont.ttf differ
diff --git a/static/assets/font/iconfont.woff b/static/assets/font/iconfont.woff
new file mode 100644
index 0000000..66a1783
Binary files /dev/null and b/static/assets/font/iconfont.woff differ
diff --git a/static/assets/font/iconfont.woff2 b/static/assets/font/iconfont.woff2
new file mode 100644
index 0000000..47e9980
Binary files /dev/null and b/static/assets/font/iconfont.woff2 differ
diff --git a/static/assets/images/face/0.gif b/static/assets/images/face/0.gif
new file mode 100644
index 0000000..a63f0d5
Binary files /dev/null and b/static/assets/images/face/0.gif differ
diff --git a/static/assets/images/face/1.gif b/static/assets/images/face/1.gif
new file mode 100644
index 0000000..b2b78b2
Binary files /dev/null and b/static/assets/images/face/1.gif differ
diff --git a/static/assets/images/face/10.gif b/static/assets/images/face/10.gif
new file mode 100644
index 0000000..556c7e3
Binary files /dev/null and b/static/assets/images/face/10.gif differ
diff --git a/static/assets/images/face/11.gif b/static/assets/images/face/11.gif
new file mode 100644
index 0000000..2bfc58b
Binary files /dev/null and b/static/assets/images/face/11.gif differ
diff --git a/static/assets/images/face/12.gif b/static/assets/images/face/12.gif
new file mode 100644
index 0000000..1c321c7
Binary files /dev/null and b/static/assets/images/face/12.gif differ
diff --git a/static/assets/images/face/13.gif b/static/assets/images/face/13.gif
new file mode 100644
index 0000000..300bbc2
Binary files /dev/null and b/static/assets/images/face/13.gif differ
diff --git a/static/assets/images/face/14.gif b/static/assets/images/face/14.gif
new file mode 100644
index 0000000..43b6d0a
Binary files /dev/null and b/static/assets/images/face/14.gif differ
diff --git a/static/assets/images/face/15.gif b/static/assets/images/face/15.gif
new file mode 100644
index 0000000..c9f25fa
Binary files /dev/null and b/static/assets/images/face/15.gif differ
diff --git a/static/assets/images/face/16.gif b/static/assets/images/face/16.gif
new file mode 100644
index 0000000..34f28e4
Binary files /dev/null and b/static/assets/images/face/16.gif differ
diff --git a/static/assets/images/face/17.gif b/static/assets/images/face/17.gif
new file mode 100644
index 0000000..39cd035
Binary files /dev/null and b/static/assets/images/face/17.gif differ
diff --git a/static/assets/images/face/18.gif b/static/assets/images/face/18.gif
new file mode 100644
index 0000000..7bce299
Binary files /dev/null and b/static/assets/images/face/18.gif differ
diff --git a/static/assets/images/face/19.gif b/static/assets/images/face/19.gif
new file mode 100644
index 0000000..adac542
Binary files /dev/null and b/static/assets/images/face/19.gif differ
diff --git a/static/assets/images/face/2.gif b/static/assets/images/face/2.gif
new file mode 100644
index 0000000..7edbb58
Binary files /dev/null and b/static/assets/images/face/2.gif differ
diff --git a/static/assets/images/face/20.gif b/static/assets/images/face/20.gif
new file mode 100644
index 0000000..50631a6
Binary files /dev/null and b/static/assets/images/face/20.gif differ
diff --git a/static/assets/images/face/21.gif b/static/assets/images/face/21.gif
new file mode 100644
index 0000000..b984212
Binary files /dev/null and b/static/assets/images/face/21.gif differ
diff --git a/static/assets/images/face/22.gif b/static/assets/images/face/22.gif
new file mode 100644
index 0000000..1f0bd8b
Binary files /dev/null and b/static/assets/images/face/22.gif differ
diff --git a/static/assets/images/face/23.gif b/static/assets/images/face/23.gif
new file mode 100644
index 0000000..e05e0f9
Binary files /dev/null and b/static/assets/images/face/23.gif differ
diff --git a/static/assets/images/face/24.gif b/static/assets/images/face/24.gif
new file mode 100644
index 0000000..f35928a
Binary files /dev/null and b/static/assets/images/face/24.gif differ
diff --git a/static/assets/images/face/25.gif b/static/assets/images/face/25.gif
new file mode 100644
index 0000000..0b4a883
Binary files /dev/null and b/static/assets/images/face/25.gif differ
diff --git a/static/assets/images/face/26.gif b/static/assets/images/face/26.gif
new file mode 100644
index 0000000..45c4fb5
Binary files /dev/null and b/static/assets/images/face/26.gif differ
diff --git a/static/assets/images/face/27.gif b/static/assets/images/face/27.gif
new file mode 100644
index 0000000..7a4c013
Binary files /dev/null and b/static/assets/images/face/27.gif differ
diff --git a/static/assets/images/face/28.gif b/static/assets/images/face/28.gif
new file mode 100644
index 0000000..fc5a0cf
Binary files /dev/null and b/static/assets/images/face/28.gif differ
diff --git a/static/assets/images/face/29.gif b/static/assets/images/face/29.gif
new file mode 100644
index 0000000..5dd7442
Binary files /dev/null and b/static/assets/images/face/29.gif differ
diff --git a/static/assets/images/face/3.gif b/static/assets/images/face/3.gif
new file mode 100644
index 0000000..86df67b
Binary files /dev/null and b/static/assets/images/face/3.gif differ
diff --git a/static/assets/images/face/30.gif b/static/assets/images/face/30.gif
new file mode 100644
index 0000000..b751f98
Binary files /dev/null and b/static/assets/images/face/30.gif differ
diff --git a/static/assets/images/face/31.gif b/static/assets/images/face/31.gif
new file mode 100644
index 0000000..c9476d7
Binary files /dev/null and b/static/assets/images/face/31.gif differ
diff --git a/static/assets/images/face/32.gif b/static/assets/images/face/32.gif
new file mode 100644
index 0000000..9931b06
Binary files /dev/null and b/static/assets/images/face/32.gif differ
diff --git a/static/assets/images/face/33.gif b/static/assets/images/face/33.gif
new file mode 100644
index 0000000..59111a3
Binary files /dev/null and b/static/assets/images/face/33.gif differ
diff --git a/static/assets/images/face/34.gif b/static/assets/images/face/34.gif
new file mode 100644
index 0000000..a334548
Binary files /dev/null and b/static/assets/images/face/34.gif differ
diff --git a/static/assets/images/face/35.gif b/static/assets/images/face/35.gif
new file mode 100644
index 0000000..a932264
Binary files /dev/null and b/static/assets/images/face/35.gif differ
diff --git a/static/assets/images/face/36.gif b/static/assets/images/face/36.gif
new file mode 100644
index 0000000..6de432a
Binary files /dev/null and b/static/assets/images/face/36.gif differ
diff --git a/static/assets/images/face/37.gif b/static/assets/images/face/37.gif
new file mode 100644
index 0000000..d05f2da
Binary files /dev/null and b/static/assets/images/face/37.gif differ
diff --git a/static/assets/images/face/38.gif b/static/assets/images/face/38.gif
new file mode 100644
index 0000000..8b1c88a
Binary files /dev/null and b/static/assets/images/face/38.gif differ
diff --git a/static/assets/images/face/39.gif b/static/assets/images/face/39.gif
new file mode 100644
index 0000000..38b84a5
Binary files /dev/null and b/static/assets/images/face/39.gif differ
diff --git a/static/assets/images/face/4.gif b/static/assets/images/face/4.gif
new file mode 100644
index 0000000..d52200c
Binary files /dev/null and b/static/assets/images/face/4.gif differ
diff --git a/static/assets/images/face/40.gif b/static/assets/images/face/40.gif
new file mode 100644
index 0000000..ae42991
Binary files /dev/null and b/static/assets/images/face/40.gif differ
diff --git a/static/assets/images/face/41.gif b/static/assets/images/face/41.gif
new file mode 100644
index 0000000..b9c715c
Binary files /dev/null and b/static/assets/images/face/41.gif differ
diff --git a/static/assets/images/face/42.gif b/static/assets/images/face/42.gif
new file mode 100644
index 0000000..0eb1434
Binary files /dev/null and b/static/assets/images/face/42.gif differ
diff --git a/static/assets/images/face/43.gif b/static/assets/images/face/43.gif
new file mode 100644
index 0000000..ac0b700
Binary files /dev/null and b/static/assets/images/face/43.gif differ
diff --git a/static/assets/images/face/44.gif b/static/assets/images/face/44.gif
new file mode 100644
index 0000000..ad44497
Binary files /dev/null and b/static/assets/images/face/44.gif differ
diff --git a/static/assets/images/face/45.gif b/static/assets/images/face/45.gif
new file mode 100644
index 0000000..6837fca
Binary files /dev/null and b/static/assets/images/face/45.gif differ
diff --git a/static/assets/images/face/46.gif b/static/assets/images/face/46.gif
new file mode 100644
index 0000000..d62916d
Binary files /dev/null and b/static/assets/images/face/46.gif differ
diff --git a/static/assets/images/face/47.gif b/static/assets/images/face/47.gif
new file mode 100644
index 0000000..58a0836
Binary files /dev/null and b/static/assets/images/face/47.gif differ
diff --git a/static/assets/images/face/48.gif b/static/assets/images/face/48.gif
new file mode 100644
index 0000000..7ffd161
Binary files /dev/null and b/static/assets/images/face/48.gif differ
diff --git a/static/assets/images/face/49.gif b/static/assets/images/face/49.gif
new file mode 100644
index 0000000..959b992
Binary files /dev/null and b/static/assets/images/face/49.gif differ
diff --git a/static/assets/images/face/5.gif b/static/assets/images/face/5.gif
new file mode 100644
index 0000000..4e8b09f
Binary files /dev/null and b/static/assets/images/face/5.gif differ
diff --git a/static/assets/images/face/50.gif b/static/assets/images/face/50.gif
new file mode 100644
index 0000000..6e22e7f
Binary files /dev/null and b/static/assets/images/face/50.gif differ
diff --git a/static/assets/images/face/51.gif b/static/assets/images/face/51.gif
new file mode 100644
index 0000000..ad3f4d3
Binary files /dev/null and b/static/assets/images/face/51.gif differ
diff --git a/static/assets/images/face/52.gif b/static/assets/images/face/52.gif
new file mode 100644
index 0000000..39f8a22
Binary files /dev/null and b/static/assets/images/face/52.gif differ
diff --git a/static/assets/images/face/53.gif b/static/assets/images/face/53.gif
new file mode 100644
index 0000000..a181ee7
Binary files /dev/null and b/static/assets/images/face/53.gif differ
diff --git a/static/assets/images/face/54.gif b/static/assets/images/face/54.gif
new file mode 100644
index 0000000..e289d92
Binary files /dev/null and b/static/assets/images/face/54.gif differ
diff --git a/static/assets/images/face/55.gif b/static/assets/images/face/55.gif
new file mode 100644
index 0000000..4351083
Binary files /dev/null and b/static/assets/images/face/55.gif differ
diff --git a/static/assets/images/face/56.gif b/static/assets/images/face/56.gif
new file mode 100644
index 0000000..e0eff22
Binary files /dev/null and b/static/assets/images/face/56.gif differ
diff --git a/static/assets/images/face/57.gif b/static/assets/images/face/57.gif
new file mode 100644
index 0000000..0bf130f
Binary files /dev/null and b/static/assets/images/face/57.gif differ
diff --git a/static/assets/images/face/58.gif b/static/assets/images/face/58.gif
new file mode 100644
index 0000000..0f06508
Binary files /dev/null and b/static/assets/images/face/58.gif differ
diff --git a/static/assets/images/face/59.gif b/static/assets/images/face/59.gif
new file mode 100644
index 0000000..7081e4f
Binary files /dev/null and b/static/assets/images/face/59.gif differ
diff --git a/static/assets/images/face/6.gif b/static/assets/images/face/6.gif
new file mode 100644
index 0000000..f7715bf
Binary files /dev/null and b/static/assets/images/face/6.gif differ
diff --git a/static/assets/images/face/60.gif b/static/assets/images/face/60.gif
new file mode 100644
index 0000000..6e15f89
Binary files /dev/null and b/static/assets/images/face/60.gif differ
diff --git a/static/assets/images/face/61.gif b/static/assets/images/face/61.gif
new file mode 100644
index 0000000..f092d7e
Binary files /dev/null and b/static/assets/images/face/61.gif differ
diff --git a/static/assets/images/face/62.gif b/static/assets/images/face/62.gif
new file mode 100644
index 0000000..7fe4984
Binary files /dev/null and b/static/assets/images/face/62.gif differ
diff --git a/static/assets/images/face/63.gif b/static/assets/images/face/63.gif
new file mode 100644
index 0000000..cf8e23e
Binary files /dev/null and b/static/assets/images/face/63.gif differ
diff --git a/static/assets/images/face/64.gif b/static/assets/images/face/64.gif
new file mode 100644
index 0000000..a779719
Binary files /dev/null and b/static/assets/images/face/64.gif differ
diff --git a/static/assets/images/face/65.gif b/static/assets/images/face/65.gif
new file mode 100644
index 0000000..7bb98f2
Binary files /dev/null and b/static/assets/images/face/65.gif differ
diff --git a/static/assets/images/face/66.gif b/static/assets/images/face/66.gif
new file mode 100644
index 0000000..bb6d077
Binary files /dev/null and b/static/assets/images/face/66.gif differ
diff --git a/static/assets/images/face/67.gif b/static/assets/images/face/67.gif
new file mode 100644
index 0000000..6e33f7c
Binary files /dev/null and b/static/assets/images/face/67.gif differ
diff --git a/static/assets/images/face/68.gif b/static/assets/images/face/68.gif
new file mode 100644
index 0000000..1a6c400
Binary files /dev/null and b/static/assets/images/face/68.gif differ
diff --git a/static/assets/images/face/69.gif b/static/assets/images/face/69.gif
new file mode 100644
index 0000000..a02f0b2
Binary files /dev/null and b/static/assets/images/face/69.gif differ
diff --git a/static/assets/images/face/7.gif b/static/assets/images/face/7.gif
new file mode 100644
index 0000000..e6d4db8
Binary files /dev/null and b/static/assets/images/face/7.gif differ
diff --git a/static/assets/images/face/70.gif b/static/assets/images/face/70.gif
new file mode 100644
index 0000000..416c5c1
Binary files /dev/null and b/static/assets/images/face/70.gif differ
diff --git a/static/assets/images/face/71.gif b/static/assets/images/face/71.gif
new file mode 100644
index 0000000..c17d60c
Binary files /dev/null and b/static/assets/images/face/71.gif differ
diff --git a/static/assets/images/face/8.gif b/static/assets/images/face/8.gif
new file mode 100644
index 0000000..66f967b
Binary files /dev/null and b/static/assets/images/face/8.gif differ
diff --git a/static/assets/images/face/9.gif b/static/assets/images/face/9.gif
new file mode 100644
index 0000000..6044740
Binary files /dev/null and b/static/assets/images/face/9.gif differ
diff --git a/static/assets/images/logo.png b/static/assets/images/logo.png
new file mode 100644
index 0000000..2d962ba
Binary files /dev/null and b/static/assets/images/logo.png differ
diff --git a/static/assets/lay/modules/carousel.js b/static/assets/lay/modules/carousel.js
new file mode 100644
index 0000000..2c4521b
--- /dev/null
+++ b/static/assets/lay/modules/carousel.js
@@ -0,0 +1,2 @@
+/** layui-v2.5.6 MIT License By https://www.layui.com */
+ ;layui.define("jquery",function(e){"use strict";var i=layui.$,n=(layui.hint(),layui.device(),{config:{},set:function(e){var n=this;return n.config=i.extend({},n.config,e),n},on:function(e,i){return layui.onevent.call(this,t,e,i)}}),t="carousel",a="layui-this",l=">*[carousel-item]>*",o="layui-carousel-left",r="layui-carousel-right",d="layui-carousel-prev",s="layui-carousel-next",u="layui-carousel-arrow",c="layui-carousel-ind",m=function(e){var t=this;t.config=i.extend({},t.config,n.config,e),t.render()};m.prototype.config={width:"600px",height:"280px",full:!1,arrow:"hover",indicator:"inside",autoplay:!0,interval:3e3,anim:"",trigger:"click",index:0},m.prototype.render=function(){var e=this,n=e.config;n.elem=i(n.elem),n.elem[0]&&(e.elemItem=n.elem.find(l),n.index<0&&(n.index=0),n.index>=e.elemItem.length&&(n.index=e.elemItem.length-1),n.interval<800&&(n.interval=800),n.full?n.elem.css({position:"fixed",width:"100%",height:"100%",zIndex:9999}):n.elem.css({width:n.width,height:n.height}),n.elem.attr("lay-anim",n.anim),e.elemItem.eq(n.index).addClass(a),e.elemItem.length<=1||(e.indicator(),e.arrow(),e.autoplay(),e.events()))},m.prototype.reload=function(e){var n=this;clearInterval(n.timer),n.config=i.extend({},n.config,e),n.render()},m.prototype.prevIndex=function(){var e=this,i=e.config,n=i.index-1;return n<0&&(n=e.elemItem.length-1),n},m.prototype.nextIndex=function(){var e=this,i=e.config,n=i.index+1;return n>=e.elemItem.length&&(n=0),n},m.prototype.addIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index+e,n.index>=i.elemItem.length&&(n.index=0)},m.prototype.subIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index-e,n.index<0&&(n.index=i.elemItem.length-1)},m.prototype.autoplay=function(){var e=this,i=e.config;i.autoplay&&(clearInterval(e.timer),e.timer=setInterval(function(){e.slide()},i.interval))},m.prototype.arrow=function(){var e=this,n=e.config,t=i(['",'"].join(""));n.elem.attr("lay-arrow",n.arrow),n.elem.find("."+u)[0]&&n.elem.find("."+u).remove(),n.elem.append(t),t.on("click",function(){var n=i(this),t=n.attr("lay-type");e.slide(t)})},m.prototype.indicator=function(){var e=this,n=e.config,t=e.elemInd=i(['
',function(){var i=[];return layui.each(e.elemItem,function(e){i.push("")}),i.join("")}(),"
"].join(""));n.elem.attr("lay-indicator",n.indicator),n.elem.find("."+c)[0]&&n.elem.find("."+c).remove(),n.elem.append(t),"updown"===n.anim&&t.css("margin-top",-(t.height()/2)),t.find("li").on("hover"===n.trigger?"mouseover":n.trigger,function(){var t=i(this),a=t.index();a>n.index?e.slide("add",a-n.index):a/g,">").replace(/'/g,"'").replace(/"/g,""")),c.html('- '+o.replace(/[\r\t\n]+/g,"
- ")+"
"),c.find(">.layui-code-h3")[0]||c.prepend(''+(c.attr("lay-title")||e.title||"code")+(e.about?'layui.code':"")+"
");var d=c.find(">.layui-code-ol");c.addClass("layui-box layui-code-view"),(c.attr("lay-skin")||e.skin)&&c.addClass("layui-code-"+(c.attr("lay-skin")||e.skin)),(d.find("li").length/100|0)>0&&d.css("margin-left",(d.find("li").length/100|0)+"px"),(c.attr("lay-height")||e.height)&&d.css("max-height",c.attr("lay-height")||e.height)})})}).addcss("modules/code.css","skincodecss");
\ No newline at end of file
diff --git a/static/assets/lay/modules/colorpicker.js b/static/assets/lay/modules/colorpicker.js
new file mode 100644
index 0000000..0fc6395
--- /dev/null
+++ b/static/assets/lay/modules/colorpicker.js
@@ -0,0 +1,2 @@
+/** layui-v2.5.6 MIT License By https://www.layui.com */
+ ;layui.define("jquery",function(e){"use strict";var i=layui.jquery,o={config:{},index:layui.colorpicker?layui.colorpicker.index+1e4:0,set:function(e){var o=this;return o.config=i.extend({},o.config,e),o},on:function(e,i){return layui.onevent.call(this,"colorpicker",e,i)}},r=function(){var e=this,i=e.config;return{config:i}},t="colorpicker",n="layui-show",l="layui-colorpicker",c=".layui-colorpicker-main",a="layui-icon-down",s="layui-icon-close",f="layui-colorpicker-trigger-span",d="layui-colorpicker-trigger-i",u="layui-colorpicker-side",p="layui-colorpicker-side-slider",g="layui-colorpicker-basis",v="layui-colorpicker-alpha-bgcolor",h="layui-colorpicker-alpha-slider",m="layui-colorpicker-basis-cursor",b="layui-colorpicker-main-input",k=function(e){var i={h:0,s:0,b:0},o=Math.min(e.r,e.g,e.b),r=Math.max(e.r,e.g,e.b),t=r-o;return i.b=r,i.s=0!=r?255*t/r:0,0!=i.s?e.r==r?i.h=(e.g-e.b)/t:e.g==r?i.h=2+(e.b-e.r)/t:i.h=4+(e.r-e.g)/t:i.h=-1,r==o&&(i.h=0),i.h*=60,i.h<0&&(i.h+=360),i.s*=100/255,i.b*=100/255,i},y=function(e){var e=e.indexOf("#")>-1?e.substring(1):e;if(3==e.length){var i=e.split("");e=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]}e=parseInt(e,16);var o={r:e>>16,g:(65280&e)>>8,b:255&e};return k(o)},x=function(e){var i={},o=e.h,r=255*e.s/100,t=255*e.b/100;if(0==r)i.r=i.g=i.b=t;else{var n=t,l=(255-r)*t/255,c=(n-l)*(o%60)/60;360==o&&(o=0),o<60?(i.r=n,i.b=l,i.g=l+c):o<120?(i.g=n,i.b=l,i.r=n-c):o<180?(i.g=n,i.r=l,i.b=l+c):o<240?(i.b=n,i.r=l,i.g=n-c):o<300?(i.b=n,i.g=l,i.r=l+c):o<360?(i.r=n,i.g=l,i.b=n-c):(i.r=0,i.g=0,i.b=0)}return{r:Math.round(i.r),g:Math.round(i.g),b:Math.round(i.b)}},C=function(e){var o=x(e),r=[o.r.toString(16),o.g.toString(16),o.b.toString(16)];return i.each(r,function(e,i){1==i.length&&(r[e]="0"+i)}),r.join("")},P=function(e){var i=/[0-9]{1,3}/g,o=e.match(i)||[];return{r:o[0],g:o[1],b:o[2]}},B=i(window),w=i(document),D=function(e){var r=this;r.index=++o.index,r.config=i.extend({},r.config,o.config,e),r.render()};D.prototype.config={color:"",size:null,alpha:!1,format:"hex",predefine:!1,colors:["#009688","#5FB878","#1E9FFF","#FF5722","#FFB800","#01AAED","#999","#c00","#ff8c00","#ffd700","#90ee90","#00ced1","#1e90ff","#c71585","rgb(0, 186, 189)","rgb(255, 120, 0)","rgb(250, 212, 0)","#393D49","rgba(0,0,0,.5)","rgba(255, 69, 0, 0.68)","rgba(144, 240, 144, 0.5)","rgba(31, 147, 255, 0.73)"]},D.prototype.render=function(){var e=this,o=e.config,r=i(['',"",'3&&(o.alpha&&"rgb"==o.format||(e="#"+C(k(P(o.color))))),"background: "+e):e}()+'">','',"","","
"].join("")),t=i(o.elem);o.size&&r.addClass("layui-colorpicker-"+o.size),t.addClass("layui-inline").html(e.elemColorBox=r),e.color=e.elemColorBox.find("."+f)[0].style.background,e.events()},D.prototype.renderPicker=function(){var e=this,o=e.config,r=e.elemColorBox[0],t=e.elemPicker=i(['','
",'
",function(){if(o.predefine){var e=['
'];return layui.each(o.colors,function(i,o){e.push(['
"].join(""))}),e.push("
"),e.join("")}return""}(),'
','
','',"
",'
','','',"
","
"].join(""));e.elemColorBox.find("."+f)[0];i(c)[0]&&i(c).data("index")==e.index?e.removePicker(D.thisElemInd):(e.removePicker(D.thisElemInd),i("body").append(t)),D.thisElemInd=e.index,D.thisColor=r.style.background,e.position(),e.pickerEvents()},D.prototype.removePicker=function(e){var o=this;o.config;return i("#layui-colorpicker"+(e||o.index)).remove(),o},D.prototype.position=function(){var e=this,i=e.config,o=e.bindElem||e.elemColorBox[0],r=e.elemPicker[0],t=o.getBoundingClientRect(),n=r.offsetWidth,l=r.offsetHeight,c=function(e){return e=e?"scrollLeft":"scrollTop",document.body[e]|document.documentElement[e]},a=function(e){return document.documentElement[e?"clientWidth":"clientHeight"]},s=5,f=t.left,d=t.bottom;f-=(n-o.offsetWidth)/2,d+=s,f+n+s>a("width")?f=a("width")-n-s:f
a()&&(d=t.top>l?t.top-l:a()-l,d-=2*s),i.position&&(r.style.position=i.position),r.style.left=f+("fixed"===i.position?0:c(1))+"px",r.style.top=d+("fixed"===i.position?0:c())+"px"},D.prototype.val=function(){var e=this,i=(e.config,e.elemColorBox.find("."+f)),o=e.elemPicker.find("."+b),r=i[0],t=r.style.backgroundColor;if(t){var n=k(P(t)),l=i.attr("lay-type");if(e.select(n.h,n.s,n.b),"torgb"===l&&o.find("input").val(t),"rgba"===l){var c=P(t);if(3==(t.match(/[0-9]{1,3}/g)||[]).length)o.find("input").val("rgba("+c.r+", "+c.g+", "+c.b+", 1)"),e.elemPicker.find("."+h).css("left",280);else{o.find("input").val(t);var a=280*t.slice(t.lastIndexOf(",")+1,t.length-1);e.elemPicker.find("."+h).css("left",a)}e.elemPicker.find("."+v)[0].style.background="linear-gradient(to right, rgba("+c.r+", "+c.g+", "+c.b+", 0), rgb("+c.r+", "+c.g+", "+c.b+"))"}}else e.select(0,100,100),o.find("input").val(""),e.elemPicker.find("."+v)[0].style.background="",e.elemPicker.find("."+h).css("left",280)},D.prototype.side=function(){var e=this,o=e.config,r=e.elemColorBox.find("."+f),t=r.attr("lay-type"),n=e.elemPicker.find("."+u),l=e.elemPicker.find("."+p),c=e.elemPicker.find("."+g),y=e.elemPicker.find("."+m),C=e.elemPicker.find("."+v),w=e.elemPicker.find("."+h),D=l[0].offsetTop/180*360,E=100-(y[0].offsetTop+3)/180*100,H=(y[0].offsetLeft+3)/260*100,W=Math.round(w[0].offsetLeft/280*100)/100,j=e.elemColorBox.find("."+d),F=e.elemPicker.find(".layui-colorpicker-pre").children("div"),L=function(i,n,l,c){e.select(i,n,l);var f=x({h:i,s:n,b:l});if(j.addClass(a).removeClass(s),r[0].style.background="rgb("+f.r+", "+f.g+", "+f.b+")","torgb"===t&&e.elemPicker.find("."+b).find("input").val("rgb("+f.r+", "+f.g+", "+f.b+")"),"rgba"===t){var d=0;d=280*c,w.css("left",d),e.elemPicker.find("."+b).find("input").val("rgba("+f.r+", "+f.g+", "+f.b+", "+c+")"),r[0].style.background="rgba("+f.r+", "+f.g+", "+f.b+", "+c+")",C[0].style.background="linear-gradient(to right, rgba("+f.r+", "+f.g+", "+f.b+", 0), rgb("+f.r+", "+f.g+", "+f.b+"))"}o.change&&o.change(e.elemPicker.find("."+b).find("input").val())},M=i(['t&&(r=t);var l=r/180*360;D=l,L(l,H,E,W),e.preventDefault()};Y(r),e.preventDefault()}),n.on("click",function(e){var o=e.clientY-i(this).offset().top;o<0&&(o=0),o>this.offsetHeight&&(o=this.offsetHeight);var r=o/180*360;D=r,L(r,H,E,W),e.preventDefault()}),y.on("mousedown",function(e){var i=this.offsetTop,o=this.offsetLeft,r=e.clientY,t=e.clientX,n=function(e){var n=i+(e.clientY-r),l=o+(e.clientX-t),a=c[0].offsetHeight-3,s=c[0].offsetWidth-3;n<-3&&(n=-3),n>a&&(n=a),l<-3&&(l=-3),l>s&&(l=s);var f=(l+3)/260*100,d=100-(n+3)/180*100;E=d,H=f,L(D,f,d,W),e.preventDefault()};layui.stope(e),Y(n),e.preventDefault()}),c.on("mousedown",function(e){var o=e.clientY-i(this).offset().top-3+B.scrollTop(),r=e.clientX-i(this).offset().left-3+B.scrollLeft();o<-3&&(o=-3),o>this.offsetHeight-3&&(o=this.offsetHeight-3),r<-3&&(r=-3),r>this.offsetWidth-3&&(r=this.offsetWidth-3);var t=(r+3)/260*100,n=100-(o+3)/180*100;E=n,H=t,L(D,t,n,W),e.preventDefault(),y.trigger(e,"mousedown")}),w.on("mousedown",function(e){var i=this.offsetLeft,o=e.clientX,r=function(e){var r=i+(e.clientX-o),t=C[0].offsetWidth;r<0&&(r=0),r>t&&(r=t);var n=Math.round(r/280*100)/100;W=n,L(D,H,E,n),e.preventDefault()};Y(r),e.preventDefault()}),C.on("click",function(e){var o=e.clientX-i(this).offset().left;o<0&&(o=0),o>this.offsetWidth&&(o=this.offsetWidth);var r=Math.round(o/280*100)/100;W=r,L(D,H,E,r),e.preventDefault()}),F.each(function(){i(this).on("click",function(){i(this).parent(".layui-colorpicker-pre").addClass("selected").siblings().removeClass("selected");var e,o=this.style.backgroundColor,r=k(P(o)),t=o.slice(o.lastIndexOf(",")+1,o.length-1);D=r.h,H=r.s,E=r.b,3==(o.match(/[0-9]{1,3}/g)||[]).length&&(t=1),W=t,e=280*t,L(r.h,r.s,r.b,t)})})},D.prototype.select=function(e,i,o,r){var t=this,n=(t.config,C({h:e,s:100,b:100})),l=C({h:e,s:i,b:o}),c=e/360*180,a=180-o/100*180-3,s=i/100*260-3;t.elemPicker.find("."+p).css("top",c),t.elemPicker.find("."+g)[0].style.background="#"+n,t.elemPicker.find("."+m).css({top:a,left:s}),"change"!==r&&t.elemPicker.find("."+b).find("input").val("#"+l)},D.prototype.pickerEvents=function(){var e=this,o=e.config,r=e.elemColorBox.find("."+f),t=e.elemPicker.find("."+b+" input"),n={clear:function(i){r[0].style.background="",e.elemColorBox.find("."+d).removeClass(a).addClass(s),e.color="",o.done&&o.done(""),e.removePicker()},confirm:function(i,n){var l=t.val(),c=l,f={};if(l.indexOf(",")>-1){if(f=k(P(l)),e.select(f.h,f.s,f.b),r[0].style.background=c="#"+C(f),(l.match(/[0-9]{1,3}/g)||[]).length>3&&"rgba"===r.attr("lay-type")){var u=280*l.slice(l.lastIndexOf(",")+1,l.length-1);e.elemPicker.find("."+h).css("left",u),r[0].style.background=l,c=l}}else f=y(l),r[0].style.background=c="#"+C(f),e.elemColorBox.find("."+d).removeClass(s).addClass(a);return"change"===n?(e.select(f.h,f.s,f.b,n),void(o.change&&o.change(c))):(e.color=l,o.done&&o.done(l),void e.removePicker())}};e.elemPicker.on("click","*[colorpicker-events]",function(){var e=i(this),o=e.attr("colorpicker-events");n[o]&&n[o].call(this,e)}),t.on("keyup",function(e){var o=i(this);n.confirm.call(this,o,13===e.keyCode?null:"change")})},D.prototype.events=function(){var e=this,o=e.config,r=e.elemColorBox.find("."+f);e.elemColorBox.on("click",function(){e.renderPicker(),i(c)[0]&&(e.val(),e.side())}),o.elem[0]&&!e.elemColorBox[0].eventHandler&&(w.on("click",function(o){if(!i(o.target).hasClass(l)&&!i(o.target).parents("."+l)[0]&&!i(o.target).hasClass(c.replace(/\./g,""))&&!i(o.target).parents(c)[0]&&e.elemPicker){if(e.color){var t=k(P(e.color));e.select(t.h,t.s,t.b)}else e.elemColorBox.find("."+d).removeClass(a).addClass(s);r[0].style.background=e.color||"",e.removePicker()}}),B.on("resize",function(){return!(!e.elemPicker||!i(c)[0])&&void e.position()}),e.elemColorBox[0].eventHandler=!0)},o.render=function(e){var i=new D(e);return r.call(i)},e(t,o)});
\ No newline at end of file
diff --git a/static/assets/lay/modules/element.js b/static/assets/lay/modules/element.js
new file mode 100644
index 0000000..290a1e8
--- /dev/null
+++ b/static/assets/lay/modules/element.js
@@ -0,0 +1,2 @@
+/** layui-v2.5.6 MIT License By https://www.layui.com */
+ ;layui.define("jquery",function(t){"use strict";var a=layui.$,i=(layui.hint(),layui.device()),e="element",l="layui-this",n="layui-show",s=function(){this.config={}};s.prototype.set=function(t){var i=this;return a.extend(!0,i.config,t),i},s.prototype.on=function(t,a){return layui.onevent.call(this,e,t,a)},s.prototype.tabAdd=function(t,i){var e=".layui-tab-title",l=a(".layui-tab[lay-filter="+t+"]"),n=l.children(e),s=n.children(".layui-tab-bar"),o=l.children(".layui-tab-content"),r='"+(i.title||"unnaming")+"";return s[0]?s.before(r):n.append(r),o.append(''+(i.content||"")+"
"),f.hideTabMore(!0),f.tabAuto(),this},s.prototype.tabDelete=function(t,i){var e=".layui-tab-title",l=a(".layui-tab[lay-filter="+t+"]"),n=l.children(e),s=n.find('>li[lay-id="'+i+'"]');return f.tabDelete(null,s),this},s.prototype.tabChange=function(t,i){var e=".layui-tab-title",l=a(".layui-tab[lay-filter="+t+"]"),n=l.children(e),s=n.find('>li[lay-id="'+i+'"]');return f.tabClick.call(s[0],null,null,s),this},s.prototype.tab=function(t){t=t||{},b.on("click",t.headerElem,function(i){var e=a(this).index();f.tabClick.call(this,i,e,null,t)})},s.prototype.progress=function(t,i){var e="layui-progress",l=a("."+e+"[lay-filter="+t+"]"),n=l.find("."+e+"-bar"),s=n.find("."+e+"-text");return n.css("width",i),s.text(i),this};var o=".layui-nav",r="layui-nav-item",c="layui-nav-bar",u="layui-nav-tree",d="layui-nav-child",y="layui-nav-more",h="layui-anim layui-anim-upbit",f={tabClick:function(t,i,s,o){o=o||{};var r=s||a(this),i=i||r.parent().children("li").index(r),c=o.headerElem?r.parent():r.parents(".layui-tab").eq(0),u=o.bodyElem?a(o.bodyElem):c.children(".layui-tab-content").children(".layui-tab-item"),d=r.find("a"),y=c.attr("lay-filter");"javascript:;"!==d.attr("href")&&"_blank"===d.attr("target")||(r.addClass(l).siblings().removeClass(l),u.eq(i).addClass(n).siblings().removeClass(n)),layui.event.call(this,e,"tab("+y+")",{elem:c,index:i})},tabDelete:function(t,i){var n=i||a(this).parent(),s=n.index(),o=n.parents(".layui-tab").eq(0),r=o.children(".layui-tab-content").children(".layui-tab-item"),c=o.attr("lay-filter");n.hasClass(l)&&(n.next()[0]?f.tabClick.call(n.next()[0],null,s+1):n.prev()[0]&&f.tabClick.call(n.prev()[0],null,s-1)),n.remove(),r.eq(s).remove(),setTimeout(function(){f.tabAuto()},50),layui.event.call(this,e,"tabDelete("+c+")",{elem:o,index:s})},tabAuto:function(){var t="layui-tab-more",e="layui-tab-bar",l="layui-tab-close",n=this;a(".layui-tab").each(function(){var s=a(this),o=s.children(".layui-tab-title"),r=(s.children(".layui-tab-content").children(".layui-tab-item"),'lay-stope="tabmore"'),c=a('');if(n===window&&8!=i.ie&&f.hideTabMore(!0),s.attr("lay-allowClose")&&o.find("li").each(function(){var t=a(this);if(!t.find("."+l)[0]){var i=a('ဆ');i.on("click",f.tabDelete),t.append(i)}}),"string"!=typeof s.attr("lay-unauto"))if(o.prop("scrollWidth")>o.outerWidth()+1){if(o.find("."+e)[0])return;o.append(c),s.attr("overflow",""),c.on("click",function(a){o[this.title?"removeClass":"addClass"](t),this.title=this.title?"":"收缩"})}else o.find("."+e).remove(),s.removeAttr("overflow")})},hideTabMore:function(t){var i=a(".layui-tab-title");t!==!0&&"tabmore"===a(t.target).attr("lay-stope")||(i.removeClass("layui-tab-more"),i.find(".layui-tab-bar").attr("title",""))},clickThis:function(){var t=a(this),i=t.parents(o),n=i.attr("lay-filter"),s=t.parent(),c=t.siblings("."+d),y="string"==typeof s.attr("lay-unselect");"javascript:;"!==t.attr("href")&&"_blank"===t.attr("target")||y||c[0]||(i.find("."+l).removeClass(l),s.addClass(l)),i.hasClass(u)&&(c.removeClass(h),c[0]&&(s["none"===c.css("display")?"addClass":"removeClass"](r+"ed"),"all"===i.attr("lay-shrink")&&s.siblings().removeClass(r+"ed"))),layui.event.call(this,e,"nav("+n+")",t)},collapse:function(){var t=a(this),i=t.find(".layui-colla-icon"),l=t.siblings(".layui-colla-content"),s=t.parents(".layui-collapse").eq(0),o=s.attr("lay-filter"),r="none"===l.css("display");if("string"==typeof s.attr("lay-accordion")){var c=s.children(".layui-colla-item").children("."+n);c.siblings(".layui-colla-title").children(".layui-colla-icon").html(""),c.removeClass(n)}l[r?"addClass":"removeClass"](n),i.html(r?"":""),layui.event.call(this,e,"collapse("+o+")",{title:t,content:l,show:r})}};s.prototype.init=function(t,e){var l=function(){return e?'[lay-filter="'+e+'"]':""}(),s={tab:function(){f.tabAuto.call({})},nav:function(){var t=200,e={},s={},p={},b=function(l,o,r){var c=a(this),f=c.find("."+d);o.hasClass(u)?l.css({top:c.position().top,height:c.children("a").outerHeight(),opacity:1}):(f.addClass(h),l.css({left:c.position().left+parseFloat(c.css("marginLeft")),top:c.position().top+c.height()-l.height()}),e[r]=setTimeout(function(){l.css({width:c.width(),opacity:1})},i.ie&&i.ie<10?0:t),clearTimeout(p[r]),"block"===f.css("display")&&clearTimeout(s[r]),s[r]=setTimeout(function(){f.addClass(n),c.find("."+y).addClass(y+"d")},300))};a(o+l).each(function(i){var l=a(this),o=a(''),h=l.find("."+r);l.find("."+c)[0]||(l.append(o),h.on("mouseenter",function(){b.call(this,o,l,i)}).on("mouseleave",function(){l.hasClass(u)||(clearTimeout(s[i]),s[i]=setTimeout(function(){l.find("."+d).removeClass(n),l.find("."+y).removeClass(y+"d")},300))}),l.on("mouseleave",function(){clearTimeout(e[i]),p[i]=setTimeout(function(){l.hasClass(u)?o.css({height:0,top:o.position().top+o.height()/2,opacity:0}):o.css({width:0,left:o.position().left+o.width()/2,opacity:0})},t)})),h.find("a").each(function(){var t=a(this),i=(t.parent(),t.siblings("."+d));i[0]&&!t.children("."+y)[0]&&t.append(''),t.off("click",f.clickThis).on("click",f.clickThis)})})},breadcrumb:function(){var t=".layui-breadcrumb";a(t+l).each(function(){var t=a(this),i="lay-separator",e=t.attr(i)||"/",l=t.find("a");l.next("span["+i+"]")[0]||(l.each(function(t){t!==l.length-1&&a(this).after(""+e+"")}),t.css("visibility","visible"))})},progress:function(){var t="layui-progress";a("."+t+l).each(function(){var i=a(this),e=i.find(".layui-progress-bar"),l=e.attr("lay-percent");e.css("width",function(){return/^.+\/.+$/.test(l)?100*new Function("return "+l)()+"%":l}()),i.attr("lay-showPercent")&&setTimeout(function(){e.html(''+l+"")},350)})},collapse:function(){var t="layui-collapse";a("."+t+l).each(function(){var t=a(this).find(".layui-colla-item");t.each(function(){var t=a(this),i=t.find(".layui-colla-title"),e=t.find(".layui-colla-content"),l="none"===e.css("display");i.find(".layui-colla-icon").remove(),i.append(''+(l?"":"")+""),i.off("click",f.collapse).on("click",f.collapse)})})}};return s[t]?s[t]():layui.each(s,function(t,a){a()})},s.prototype.render=s.prototype.init;var p=new s,b=a(document);p.render();var v=".layui-tab-title li";b.on("click",v,f.tabClick),b.on("click",f.hideTabMore),a(window).on("resize",f.tabAuto),t(e,p)});
\ No newline at end of file
diff --git a/static/assets/lay/modules/flow.js b/static/assets/lay/modules/flow.js
new file mode 100644
index 0000000..924c78d
--- /dev/null
+++ b/static/assets/lay/modules/flow.js
@@ -0,0 +1,2 @@
+/** layui-v2.5.6 MIT License By https://www.layui.com */
+ ;layui.define("jquery",function(e){"use strict";var l=layui.$,o=function(e){},t='';o.prototype.load=function(e){var o,i,n,r,a=this,c=0;e=e||{};var f=l(e.elem);if(f[0]){var m=l(e.scrollElem||document),u=e.mb||50,s=!("isAuto"in e)||e.isAuto,v=e.end||"没有更多了",y=e.scrollElem&&e.scrollElem!==document,d="加载更多",h=l('");f.find(".layui-flow-more")[0]||f.append(h);var p=function(e,t){e=l(e),h.before(e),t=0==t||null,t?h.html(v):h.find("a").html(d),i=t,o=null,n&&n()},g=function(){o=!0,h.find("a").html(t),"function"==typeof e.done&&e.done(++c,p)};if(g(),h.find("a").on("click",function(){l(this);i||o||g()}),e.isLazyimg)var n=a.lazyimg({elem:e.elem+" img",scrollElem:e.scrollElem});return s?(m.on("scroll",function(){var e=l(this),t=e.scrollTop();r&&clearTimeout(r),!i&&f.width()&&(r=setTimeout(function(){var i=y?e.height():l(window).height(),n=y?e.prop("scrollHeight"):document.documentElement.scrollHeight;n-t-i<=u&&(o||g())},100))}),a):a}},o.prototype.lazyimg=function(e){var o,t=this,i=0;e=e||{};var n=l(e.scrollElem||document),r=e.elem||"img",a=e.scrollElem&&e.scrollElem!==document,c=function(e,l){var o=n.scrollTop(),r=o+l,c=a?function(){return e.offset().top-n.offset().top+o}():e.offset().top;if(c>=o&&c<=r&&!e.attr("src")){var m=e.attr("lay-src");layui.img(m,function(){var l=t.lazyimg.elem.eq(i);e.attr("src",m).removeAttr("lay-src"),l[0]&&f(l),i++})}},f=function(e,o){var f=a?(o||n).height():l(window).height(),m=n.scrollTop(),u=m+f;if(t.lazyimg.elem=l(r),e)c(e,f);else for(var s=0;su)break}};if(f(),!o){var m;n.on("scroll",function(){var e=l(this);m&&clearTimeout(m),m=setTimeout(function(){f(null,e)},50)}),o=!0}return f},e("flow",new o)});
\ No newline at end of file
diff --git a/static/assets/lay/modules/form.js b/static/assets/lay/modules/form.js
new file mode 100644
index 0000000..818dd39
--- /dev/null
+++ b/static/assets/lay/modules/form.js
@@ -0,0 +1,2 @@
+/** layui-v2.5.6 MIT License By https://www.layui.com */
+ ;layui.define("layer",function(e){"use strict";var t=layui.$,i=layui.layer,a=layui.hint(),n=layui.device(),l="form",r=".layui-form",s="layui-this",o="layui-hide",c="layui-disabled",u=function(){this.config={verify:{required:[/[\S]+/,"必填项不能为空"],phone:[/^1\d{10}$/,"请输入正确的手机号"],email:[/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/,"邮箱格式不正确"],url:[/(^#)|(^http(s*):\/\/[^\s]+\.[^\s]+)/,"链接格式不正确"],number:function(e){if(!e||isNaN(e))return"只能填写数字"},date:[/^(\d{4})[-\/](\d{1}|0\d{1}|1[0-2])([-\/](\d{1}|0\d{1}|[1-2][0-9]|3[0-1]))*$/,"日期格式不正确"],identity:[/(^\d{15}$)|(^\d{17}(x|X|\d)$)/,"请输入正确的身份证号"]}}};u.prototype.set=function(e){var i=this;return t.extend(!0,i.config,e),i},u.prototype.verify=function(e){var i=this;return t.extend(!0,i.config.verify,e),i},u.prototype.on=function(e,t){return layui.onevent.call(this,l,e,t)},u.prototype.val=function(e,i){var a=this,n=t(r+'[lay-filter="'+e+'"]');return n.each(function(e,a){var n=t(this);layui.each(i,function(e,t){var i,a=n.find('[name="'+e+'"]');a[0]&&(i=a[0].type,"checkbox"===i?a[0].checked=t:"radio"===i?a.each(function(){this.value==t&&(this.checked=!0)}):a.val(t))})}),f.render(null,e),a.getValue(e)},u.prototype.getValue=function(e,i){i=i||t(r+'[lay-filter="'+e+'"]').eq(0);var a={},n={},l=i.find("input,select,textarea");return layui.each(l,function(e,t){if(t.name=(t.name||"").replace(/^\s*|\s*&/,""),t.name){if(/^.*\[\]$/.test(t.name)){var i=t.name.match(/^(.*)\[\]$/g)[0];a[i]=0|a[i],t.name=t.name.replace(/^(.*)\[\]$/,"$1["+a[i]++ +"]")}/^checkbox|radio$/.test(t.type)&&!t.checked||(n[t.name]=t.value)}}),n},u.prototype.render=function(e,i){var n=this,u=t(r+function(){return i?'[lay-filter="'+i+'"]':""}()),d={select:function(){var e,i="请选择",a="layui-form-select",n="layui-select-title",r="layui-select-none",d="",f=u.find("select"),v=function(i,l){t(i.target).parent().hasClass(n)&&!l||(t("."+a).removeClass(a+"ed "+a+"up"),e&&d&&e.val(d)),e=null},y=function(i,u,f){var y,p=t(this),m=i.find("."+n),k=m.find("input"),g=i.find("dl"),x=g.children("dd"),b=this.selectedIndex;if(!u){var C=function(){var e=i.offset().top+i.outerHeight()+5-h.scrollTop(),t=g.outerHeight();b=p[0].selectedIndex,i.addClass(a+"ed"),x.removeClass(o),y=null,x.eq(b).addClass(s).siblings().removeClass(s),e+t>h.height()&&e>=t&&i.addClass(a+"up"),T()},w=function(e){i.removeClass(a+"ed "+a+"up"),k.blur(),y=null,e||$(k.val(),function(e){var i=p[0].selectedIndex;e&&(d=t(p[0].options[i]).html(),0===i&&d===k.attr("placeholder")&&(d=""),k.val(d||""))})},T=function(){var e=g.children("dd."+s);if(e[0]){var t=e.position().top,i=g.height(),a=e.height();t>i&&g.scrollTop(t+g.scrollTop()-i+a-5),t<0&&g.scrollTop(t+g.scrollTop()-5)}};m.on("click",function(e){i.hasClass(a+"ed")?w():(v(e,!0),C()),g.find("."+r).remove()}),m.find(".layui-edge").on("click",function(){k.focus()}),k.on("keyup",function(e){var t=e.keyCode;9===t&&C()}).on("keydown",function(e){var t=e.keyCode;9===t&&w();var i=function(t,a){var n,l;e.preventDefault();var r=function(){var e=g.children("dd."+s);if(g.children("dd."+o)[0]&&"next"===t){var i=g.children("dd:not(."+o+",."+c+")"),n=i.eq(0).index();if(n>=0&&n无匹配项'):g.find("."+r).remove()},"keyup"),""===t&&g.find("."+r).remove(),void T())};f&&k.on("keyup",q).on("blur",function(i){var a=p[0].selectedIndex;e=k,d=t(p[0].options[a]).html(),0===a&&d===k.attr("placeholder")&&(d=""),setTimeout(function(){$(k.val(),function(e){d||k.val("")},"blur")},200)}),x.on("click",function(){var e=t(this),a=e.attr("lay-value"),n=p.attr("lay-filter");return!e.hasClass(c)&&(e.hasClass("layui-select-tips")?k.val(""):(k.val(e.text()),e.addClass(s)),e.siblings().removeClass(s),p.val(a).removeClass("layui-form-danger"),layui.event.call(this,l,"select("+n+")",{elem:p[0],value:a,othis:i}),w(!0),!1)}),i.find("dl>dt").on("click",function(e){return!1}),t(document).off("click",v).on("click",v)}};f.each(function(e,l){var r=t(this),o=r.next("."+a),u=this.disabled,d=l.value,f=t(l.options[l.selectedIndex]),v=l.options[0];if("string"==typeof r.attr("lay-ignore"))return r.show();var h="string"==typeof r.attr("lay-search"),p=v?v.value?i:v.innerHTML||i:i,m=t(['','
','','
','
',function(e){var t=[];return layui.each(e,function(e,a){0!==e||a.value?"optgroup"===a.tagName.toLowerCase()?t.push("- "+a.label+"
"):t.push('- '+a.innerHTML+"
"):t.push('- '+(a.innerHTML||i)+"
")}),0===t.length&&t.push('- 没有选项
'),t.join("")}(r.find("*"))+"
","
"].join(""));o[0]&&o.remove(),r.after(m),y.call(this,m,u,h)})},checkbox:function(){var e={checkbox:["layui-form-checkbox","layui-form-checked","checkbox"],_switch:["layui-form-switch","layui-form-onswitch","switch"]},i=u.find("input[type=checkbox]"),a=function(e,i){var a=t(this);e.on("click",function(){var t=a.attr("lay-filter"),n=(a.attr("lay-text")||"").split("|");a[0].disabled||(a[0].checked?(a[0].checked=!1,e.removeClass(i[1]).find("em").text(n[1])):(a[0].checked=!0,e.addClass(i[1]).find("em").text(n[0])),layui.event.call(a[0],l,i[2]+"("+t+")",{elem:a[0],value:a[0].value,othis:e}))})};i.each(function(i,n){var l=t(this),r=l.attr("lay-skin"),s=(l.attr("lay-text")||"").split("|"),o=this.disabled;"switch"===r&&(r="_"+r);var u=e[r]||e.checkbox;if("string"==typeof l.attr("lay-ignore"))return l.show();var d=l.next("."+u[0]),f=t(['",function(){var e=n.title.replace(/\s/g,""),t={checkbox:[e?""+n.title+"":"",''].join(""),_switch:""+((n.checked?s[0]:s[1])||"")+""};return t[r]||t.checkbox}(),"
"].join(""));d[0]&&d.remove(),l.after(f),a.call(this,f,u)})},radio:function(){var e="layui-form-radio",i=["",""],a=u.find("input[type=radio]"),n=function(a){var n=t(this),s="layui-anim-scaleSpring";a.on("click",function(){var o=n[0].name,c=n.parents(r),u=n.attr("lay-filter"),d=c.find("input[name="+o.replace(/(\.|#|\[|\])/g,"\\$1")+"]");n[0].disabled||(layui.each(d,function(){var a=t(this).next("."+e);this.checked=!1,a.removeClass(e+"ed"),a.find(".layui-icon").removeClass(s).html(i[1])}),n[0].checked=!0,a.addClass(e+"ed"),a.find(".layui-icon").addClass(s).html(i[0]),layui.event.call(n[0],l,"radio("+u+")",{elem:n[0],value:n[0].value,othis:a}))})};a.each(function(a,l){var r=t(this),s=r.next("."+e),o=this.disabled;if("string"==typeof r.attr("lay-ignore"))return r.show();s[0]&&s.remove();var u=t(['','
'+i[l.checked?0:1]+"","
"+function(){var e=l.title||"";return"string"==typeof r.next().attr("lay-radio")&&(e=r.next().html(),r.next().remove()),e}()+"
","
"].join(""));r.after(u),n.call(this,u)})}};return e?d[e]?d[e]():a.error("不支持的"+e+"表单渲染"):layui.each(d,function(e,t){t()}),n};var d=function(){var e=null,a=f.config.verify,s="layui-form-danger",o={},c=t(this),u=c.parents(r),d=u.find("*[lay-verify]"),v=c.parents("form")[0],h=c.attr("lay-filter");return layui.each(d,function(l,r){var o=t(this),c=o.attr("lay-verify").split("|"),u=o.attr("lay-verType"),d=o.val();if(o.removeClass(s),layui.each(c,function(t,l){var c,f="",v="function"==typeof a[l];if(a[l]){var c=v?f=a[l](d,r):!a[l][0].test(d);if(f=f||a[l][1],"required"===l&&(f=o.attr("lay-reqText")||f),c)return"tips"===u?i.tips(f,function(){return"string"==typeof o.attr("lay-ignore")||"select"!==r.tagName.toLowerCase()&&!/^checkbox|radio$/.test(r.type)?o:o.next()}(),{tips:1}):"alert"===u?i.alert(f,{title:"提示",shadeClose:!0}):i.msg(f,{icon:5,shift:6}),n.android||n.ios||setTimeout(function(){r.focus()},7),o.addClass(s),e=!0}}),e)return e}),!e&&(o=f.getValue(null,u),layui.event.call(this,l,"submit("+h+")",{elem:this,form:v,field:o}))},f=new u,v=t(document),h=t(window);f.render(),v.on("reset",r,function(){var e=t(this).attr("lay-filter");setTimeout(function(){f.render(null,e)},50)}),v.on("submit",r,d).on("click","*[lay-submit]",d),e(l,f)});
\ No newline at end of file
diff --git a/static/assets/lay/modules/jquery.js b/static/assets/lay/modules/jquery.js
new file mode 100644
index 0000000..10d8c2b
--- /dev/null
+++ b/static/assets/lay/modules/jquery.js
@@ -0,0 +1,5 @@
+/** layui-v2.5.6 MIT License By https://www.layui.com */
+ ;!function(e,t){"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){function n(e){var t=!!e&&"length"in e&&e.length,n=pe.type(e);return"function"!==n&&!pe.isWindow(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}function r(e,t,n){if(pe.isFunction(t))return pe.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return pe.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(Ce.test(t))return pe.filter(t,e,n);t=pe.filter(t,e)}return pe.grep(e,function(e){return pe.inArray(e,t)>-1!==n})}function i(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}function o(e){var t={};return pe.each(e.match(De)||[],function(e,n){t[n]=!0}),t}function a(){re.addEventListener?(re.removeEventListener("DOMContentLoaded",s),e.removeEventListener("load",s)):(re.detachEvent("onreadystatechange",s),e.detachEvent("onload",s))}function s(){(re.addEventListener||"load"===e.event.type||"complete"===re.readyState)&&(a(),pe.ready())}function u(e,t,n){if(void 0===n&&1===e.nodeType){var r="data-"+t.replace(_e,"-$1").toLowerCase();if(n=e.getAttribute(r),"string"==typeof n){try{n="true"===n||"false"!==n&&("null"===n?null:+n+""===n?+n:qe.test(n)?pe.parseJSON(n):n)}catch(i){}pe.data(e,t,n)}else n=void 0}return n}function l(e){var t;for(t in e)if(("data"!==t||!pe.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}function c(e,t,n,r){if(He(e)){var i,o,a=pe.expando,s=e.nodeType,u=s?pe.cache:e,l=s?e[a]:e[a]&&a;if(l&&u[l]&&(r||u[l].data)||void 0!==n||"string"!=typeof t)return l||(l=s?e[a]=ne.pop()||pe.guid++:a),u[l]||(u[l]=s?{}:{toJSON:pe.noop}),"object"!=typeof t&&"function"!=typeof t||(r?u[l]=pe.extend(u[l],t):u[l].data=pe.extend(u[l].data,t)),o=u[l],r||(o.data||(o.data={}),o=o.data),void 0!==n&&(o[pe.camelCase(t)]=n),"string"==typeof t?(i=o[t],null==i&&(i=o[pe.camelCase(t)])):i=o,i}}function f(e,t,n){if(He(e)){var r,i,o=e.nodeType,a=o?pe.cache:e,s=o?e[pe.expando]:pe.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){pe.isArray(t)?t=t.concat(pe.map(t,pe.camelCase)):t in r?t=[t]:(t=pe.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;for(;i--;)delete r[t[i]];if(n?!l(r):!pe.isEmptyObject(r))return}(n||(delete a[s].data,l(a[s])))&&(o?pe.cleanData([e],!0):fe.deleteExpando||a!=a.window?delete a[s]:a[s]=void 0)}}}function d(e,t,n,r){var i,o=1,a=20,s=r?function(){return r.cur()}:function(){return pe.css(e,t,"")},u=s(),l=n&&n[3]||(pe.cssNumber[t]?"":"px"),c=(pe.cssNumber[t]||"px"!==l&&+u)&&Me.exec(pe.css(e,t));if(c&&c[3]!==l){l=l||c[3],n=n||[],c=+u||1;do o=o||".5",c/=o,pe.style(e,t,c+l);while(o!==(o=s()/u)&&1!==o&&--a)}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}function p(e){var t=ze.split("|"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}function h(e,t){var n,r,i=0,o="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):void 0;if(!o)for(o=[],n=e.childNodes||e;null!=(r=n[i]);i++)!t||pe.nodeName(r,t)?o.push(r):pe.merge(o,h(r,t));return void 0===t||t&&pe.nodeName(e,t)?pe.merge([e],o):o}function g(e,t){for(var n,r=0;null!=(n=e[r]);r++)pe._data(n,"globalEval",!t||pe._data(t[r],"globalEval"))}function m(e){Be.test(e.type)&&(e.defaultChecked=e.checked)}function y(e,t,n,r,i){for(var o,a,s,u,l,c,f,d=e.length,y=p(t),v=[],x=0;x"!==f[1]||Ve.test(a)?0:u:u.firstChild,o=a&&a.childNodes.length;o--;)pe.nodeName(c=a.childNodes[o],"tbody")&&!c.childNodes.length&&a.removeChild(c);for(pe.merge(v,u.childNodes),u.textContent="";u.firstChild;)u.removeChild(u.firstChild);u=y.lastChild}else v.push(t.createTextNode(a));for(u&&y.removeChild(u),fe.appendChecked||pe.grep(h(v,"input"),m),x=0;a=v[x++];)if(r&&pe.inArray(a,r)>-1)i&&i.push(a);else if(s=pe.contains(a.ownerDocument,a),u=h(y.appendChild(a),"script"),s&&g(u),n)for(o=0;a=u[o++];)Ie.test(a.type||"")&&n.push(a);return u=null,y}function v(){return!0}function x(){return!1}function b(){try{return re.activeElement}catch(e){}}function w(e,t,n,r,i,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(s in t)w(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),i===!1)i=x;else if(!i)return e;return 1===o&&(a=i,i=function(e){return pe().off(e),a.apply(this,arguments)},i.guid=a.guid||(a.guid=pe.guid++)),e.each(function(){pe.event.add(this,t,i,r,n)})}function T(e,t){return pe.nodeName(e,"table")&&pe.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function C(e){return e.type=(null!==pe.find.attr(e,"type"))+"/"+e.type,e}function E(e){var t=it.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function N(e,t){if(1===t.nodeType&&pe.hasData(e)){var n,r,i,o=pe._data(e),a=pe._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;r1&&"string"==typeof p&&!fe.checkClone&&rt.test(p))return e.each(function(i){var o=e.eq(i);g&&(t[0]=p.call(this,i,o.html())),S(o,t,n,r)});if(f&&(l=y(t,e[0].ownerDocument,!1,e,r),i=l.firstChild,1===l.childNodes.length&&(l=i),i||r)){for(s=pe.map(h(l,"script"),C),a=s.length;c")).appendTo(t.documentElement),t=(ut[0].contentWindow||ut[0].contentDocument).document,t.write(),t.close(),n=D(e,t),ut.detach()),lt[e]=n),n}function L(e,t){return{get:function(){return e()?void delete this.get:(this.get=t).apply(this,arguments)}}}function H(e){if(e in Et)return e;for(var t=e.charAt(0).toUpperCase()+e.slice(1),n=Ct.length;n--;)if(e=Ct[n]+t,e in Et)return e}function q(e,t){for(var n,r,i,o=[],a=0,s=e.length;a=0&&n=0},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},isPlainObject:function(e){var t;if(!e||"object"!==pe.type(e)||e.nodeType||pe.isWindow(e))return!1;try{if(e.constructor&&!ce.call(e,"constructor")&&!ce.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}if(!fe.ownFirst)for(t in e)return ce.call(e,t);for(t in e);return void 0===t||ce.call(e,t)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?ue[le.call(e)]||"object":typeof e},globalEval:function(t){t&&pe.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(ge,"ms-").replace(me,ye)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t){var r,i=0;if(n(e))for(r=e.length;iT.cacheLength&&delete e[t.shift()],e[n+" "]=r}var t=[];return e}function r(e){return e[P]=!0,e}function i(e){var t=H.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function o(e,t){for(var n=e.split("|"),r=n.length;r--;)T.attrHandle[n[r]]=t}function a(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||V)-(~e.sourceIndex||V);if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function s(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function u(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function l(e){return r(function(t){return t=+t,r(function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function c(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function f(){}function d(e){for(var t=0,n=e.length,r="";t1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function g(e,n,r){for(var i=0,o=n.length;i-1&&(r[l]=!(a[l]=f))}}else x=m(x===a?x.splice(h,x.length):x),o?o(null,a,x,u):Q.apply(a,x)})}function v(e){for(var t,n,r,i=e.length,o=T.relative[e[0].type],a=o||T.relative[" "],s=o?1:0,u=p(function(e){return e===t},a,!0),l=p(function(e){return ee(t,e)>-1},a,!0),c=[function(e,n,r){var i=!o&&(r||n!==A)||((t=n).nodeType?u(e,n,r):l(e,n,r));return t=null,i}];s1&&h(c),s>1&&d(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace(se,"$1"),n,s0,o=e.length>0,a=function(r,a,s,u,l){var c,f,d,p=0,h="0",g=r&&[],y=[],v=A,x=r||o&&T.find.TAG("*",l),b=W+=null==v?1:Math.random()||.1,w=x.length;for(l&&(A=a===H||a||l);h!==w&&null!=(c=x[h]);h++){if(o&&c){for(f=0,a||c.ownerDocument===H||(L(c),s=!_);d=e[f++];)if(d(c,a||H,s)){u.push(c);break}l&&(W=b)}i&&((c=!d&&c)&&p--,r&&g.push(c))}if(p+=h,i&&h!==p){for(f=0;d=n[f++];)d(g,y,a,s);if(r){if(p>0)for(;h--;)g[h]||y[h]||(y[h]=G.call(u));y=m(y)}Q.apply(u,y),l&&!r&&y.length>0&&p+n.length>1&&t.uniqueSort(u)}return l&&(W=b,A=v),g};return i?r(a):a}var b,w,T,C,E,N,k,S,A,D,j,L,H,q,_,F,M,O,R,P="sizzle"+1*new Date,B=e.document,W=0,I=0,$=n(),z=n(),X=n(),U=function(e,t){return e===t&&(j=!0),0},V=1<<31,Y={}.hasOwnProperty,J=[],G=J.pop,K=J.push,Q=J.push,Z=J.slice,ee=function(e,t){for(var n=0,r=e.length;n+~]|"+ne+")"+ne+"*"),ce=new RegExp("="+ne+"*([^\\]'\"]*?)"+ne+"*\\]","g"),fe=new RegExp(oe),de=new RegExp("^"+re+"$"),pe={ID:new RegExp("^#("+re+")"),CLASS:new RegExp("^\\.("+re+")"),TAG:new RegExp("^("+re+"|[*])"),ATTR:new RegExp("^"+ie),PSEUDO:new RegExp("^"+oe),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ne+"*(even|odd|(([+-]|)(\\d*)n|)"+ne+"*(?:([+-]|)"+ne+"*(\\d+)|))"+ne+"*\\)|)","i"),bool:new RegExp("^(?:"+te+")$","i"),needsContext:new RegExp("^"+ne+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ne+"*((?:-\\d)?\\d*)"+ne+"*\\)|)(?=[^-]|$)","i")},he=/^(?:input|select|textarea|button)$/i,ge=/^h\d$/i,me=/^[^{]+\{\s*\[native \w/,ye=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ve=/[+~]/,xe=/'|\\/g,be=new RegExp("\\\\([\\da-f]{1,6}"+ne+"?|("+ne+")|.)","ig"),we=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},Te=function(){L()};try{Q.apply(J=Z.call(B.childNodes),B.childNodes),J[B.childNodes.length].nodeType}catch(Ce){Q={apply:J.length?function(e,t){K.apply(e,Z.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}w=t.support={},E=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},L=t.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:B;return r!==H&&9===r.nodeType&&r.documentElement?(H=r,q=H.documentElement,_=!E(H),(n=H.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",Te,!1):n.attachEvent&&n.attachEvent("onunload",Te)),w.attributes=i(function(e){return e.className="i",!e.getAttribute("className")}),w.getElementsByTagName=i(function(e){return e.appendChild(H.createComment("")),!e.getElementsByTagName("*").length}),w.getElementsByClassName=me.test(H.getElementsByClassName),w.getById=i(function(e){return q.appendChild(e).id=P,!H.getElementsByName||!H.getElementsByName(P).length}),w.getById?(T.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&_){var n=t.getElementById(e);return n?[n]:[]}},T.filter.ID=function(e){var t=e.replace(be,we);return function(e){return e.getAttribute("id")===t}}):(delete T.find.ID,T.filter.ID=function(e){var t=e.replace(be,we);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}}),T.find.TAG=w.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):w.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},T.find.CLASS=w.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&_)return t.getElementsByClassName(e)},M=[],F=[],(w.qsa=me.test(H.querySelectorAll))&&(i(function(e){q.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&F.push("[*^$]="+ne+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||F.push("\\["+ne+"*(?:value|"+te+")"),e.querySelectorAll("[id~="+P+"-]").length||F.push("~="),e.querySelectorAll(":checked").length||F.push(":checked"),e.querySelectorAll("a#"+P+"+*").length||F.push(".#.+[+~]")}),i(function(e){var t=H.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&F.push("name"+ne+"*[*^$|!~]?="),e.querySelectorAll(":enabled").length||F.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),F.push(",.*:")})),(w.matchesSelector=me.test(O=q.matches||q.webkitMatchesSelector||q.mozMatchesSelector||q.oMatchesSelector||q.msMatchesSelector))&&i(function(e){w.disconnectedMatch=O.call(e,"div"),O.call(e,"[s!='']:x"),M.push("!=",oe)}),F=F.length&&new RegExp(F.join("|")),M=M.length&&new RegExp(M.join("|")),t=me.test(q.compareDocumentPosition),R=t||me.test(q.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},U=t?function(e,t){if(e===t)return j=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n?n:(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&n||!w.sortDetached&&t.compareDocumentPosition(e)===n?e===H||e.ownerDocument===B&&R(B,e)?-1:t===H||t.ownerDocument===B&&R(B,t)?1:D?ee(D,e)-ee(D,t):0:4&n?-1:1)}:function(e,t){if(e===t)return j=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,s=[e],u=[t];if(!i||!o)return e===H?-1:t===H?1:i?-1:o?1:D?ee(D,e)-ee(D,t):0;if(i===o)return a(e,t);for(n=e;n=n.parentNode;)s.unshift(n);for(n=t;n=n.parentNode;)u.unshift(n);for(;s[r]===u[r];)r++;return r?a(s[r],u[r]):s[r]===B?-1:u[r]===B?1:0},H):H},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==H&&L(e),n=n.replace(ce,"='$1']"),w.matchesSelector&&_&&!X[n+" "]&&(!M||!M.test(n))&&(!F||!F.test(n)))try{var r=O.call(e,n);if(r||w.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(i){}return t(n,H,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==H&&L(e),R(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==H&&L(e);var n=T.attrHandle[t.toLowerCase()],r=n&&Y.call(T.attrHandle,t.toLowerCase())?n(e,t,!_):void 0;return void 0!==r?r:w.attributes||!_?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},t.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},t.uniqueSort=function(e){var t,n=[],r=0,i=0;if(j=!w.detectDuplicates,D=!w.sortStable&&e.slice(0),e.sort(U),j){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return D=null,e},C=t.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=C(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r++];)n+=C(t);return n},T=t.selectors={cacheLength:50,createPseudo:r,match:pe,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(be,we),e[3]=(e[3]||e[4]||e[5]||"").replace(be,we),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return pe.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&fe.test(n)&&(t=N(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(be,we).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=$[e+" "];return t||(t=new RegExp("(^|"+ne+")"+e+"("+ne+"|$)"))&&$(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,n,r){return function(i){var o=t.attr(i,e);return null==o?"!="===n:!n||(o+="","="===n?o===r:"!="===n?o!==r:"^="===n?r&&0===o.indexOf(r):"*="===n?r&&o.indexOf(r)>-1:"$="===n?r&&o.slice(-r.length)===r:"~="===n?(" "+o.replace(ae," ")+" ").indexOf(r)>-1:"|="===n&&(o===r||o.slice(0,r.length+1)===r+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,d,p,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s,x=!1;if(m){if(o){for(;g;){for(d=t;d=d[g];)if(s?d.nodeName.toLowerCase()===y:1===d.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){for(d=m,f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),
+l=c[e]||[],p=l[0]===W&&l[1],x=p&&l[2],d=p&&m.childNodes[p];d=++p&&d&&d[g]||(x=p=0)||h.pop();)if(1===d.nodeType&&++x&&d===t){c[e]=[W,p,x];break}}else if(v&&(d=t,f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),l=c[e]||[],p=l[0]===W&&l[1],x=p),x===!1)for(;(d=++p&&d&&d[g]||(x=p=0)||h.pop())&&((s?d.nodeName.toLowerCase()!==y:1!==d.nodeType)||!++x||(v&&(f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),c[e]=[W,x]),d!==t)););return x-=i,x===r||x%r===0&&x/r>=0}}},PSEUDO:function(e,n){var i,o=T.pseudos[e]||T.setFilters[e.toLowerCase()]||t.error("unsupported pseudo: "+e);return o[P]?o(n):o.length>1?(i=[e,e,"",n],T.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,t){for(var r,i=o(e,n),a=i.length;a--;)r=ee(e,i[a]),e[r]=!(t[r]=i[a])}):function(e){return o(e,0,i)}):o}},pseudos:{not:r(function(e){var t=[],n=[],i=k(e.replace(se,"$1"));return i[P]?r(function(e,t,n,r){for(var o,a=i(e,null,r,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,r,o){return t[0]=e,i(t,null,o,n),t[0]=null,!n.pop()}}),has:r(function(e){return function(n){return t(e,n).length>0}}),contains:r(function(e){return e=e.replace(be,we),function(t){return(t.textContent||t.innerText||C(t)).indexOf(e)>-1}}),lang:r(function(e){return de.test(e||"")||t.error("unsupported lang: "+e),e=e.replace(be,we).toLowerCase(),function(t){var n;do if(n=_?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===q},focus:function(e){return e===H.activeElement&&(!H.hasFocus||H.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!T.pseudos.empty(e)},header:function(e){return ge.test(e.nodeName)},input:function(e){return he.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:l(function(){return[0]}),last:l(function(e,t){return[t-1]}),eq:l(function(e,t,n){return[n<0?n+t:n]}),even:l(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:l(function(e,t,n){for(var r=n<0?n+t:n;++r2&&"ID"===(a=o[0]).type&&w.getById&&9===t.nodeType&&_&&T.relative[o[1].type]){if(t=(T.find.ID(a.matches[0].replace(be,we),t)||[])[0],!t)return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}for(i=pe.needsContext.test(e)?0:o.length;i--&&(a=o[i],!T.relative[s=a.type]);)if((u=T.find[s])&&(r=u(a.matches[0].replace(be,we),ve.test(o[0].type)&&c(t.parentNode)||t))){if(o.splice(i,1),e=r.length&&d(o),!e)return Q.apply(n,r),n;break}}return(l||k(e,f))(r,t,!_,n,!t||ve.test(e)&&c(t.parentNode)||t),n},w.sortStable=P.split("").sort(U).join("")===P,w.detectDuplicates=!!j,L(),w.sortDetached=i(function(e){return 1&e.compareDocumentPosition(H.createElement("div"))}),i(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||o("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),w.attributes&&i(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||o("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),i(function(e){return null==e.getAttribute("disabled")})||o(te,function(e,t,n){var r;if(!n)return e[t]===!0?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),t}(e);pe.find=ve,pe.expr=ve.selectors,pe.expr[":"]=pe.expr.pseudos,pe.uniqueSort=pe.unique=ve.uniqueSort,pe.text=ve.getText,pe.isXMLDoc=ve.isXML,pe.contains=ve.contains;var xe=function(e,t,n){for(var r=[],i=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&pe(e).is(n))break;r.push(e)}return r},be=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},we=pe.expr.match.needsContext,Te=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,Ce=/^.[^:#\[\.,]*$/;pe.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?pe.find.matchesSelector(r,e)?[r]:[]:pe.find.matches(e,pe.grep(t,function(e){return 1===e.nodeType}))},pe.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(pe(e).filter(function(){for(t=0;t1?pe.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},filter:function(e){return this.pushStack(r(this,e||[],!1))},not:function(e){return this.pushStack(r(this,e||[],!0))},is:function(e){return!!r(this,"string"==typeof e&&we.test(e)?pe(e):e||[],!1).length}});var Ee,Ne=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,ke=pe.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||Ee,"string"==typeof e){if(r="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:Ne.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof pe?t[0]:t,pe.merge(this,pe.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:re,!0)),Te.test(r[1])&&pe.isPlainObject(t))for(r in t)pe.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}if(i=re.getElementById(r[2]),i&&i.parentNode){if(i.id!==r[2])return Ee.find(e);this.length=1,this[0]=i}return this.context=re,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):pe.isFunction(e)?"undefined"!=typeof n.ready?n.ready(e):e(pe):(void 0!==e.selector&&(this.selector=e.selector,this.context=e.context),pe.makeArray(e,this))};ke.prototype=pe.fn,Ee=pe(re);var Se=/^(?:parents|prev(?:Until|All))/,Ae={children:!0,contents:!0,next:!0,prev:!0};pe.fn.extend({has:function(e){var t,n=pe(e,this),r=n.length;return this.filter(function(){for(t=0;t-1:1===n.nodeType&&pe.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?pe.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?pe.inArray(this[0],pe(e)):pe.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(pe.uniqueSort(pe.merge(this.get(),pe(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),pe.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return xe(e,"parentNode")},parentsUntil:function(e,t,n){return xe(e,"parentNode",n)},next:function(e){return i(e,"nextSibling")},prev:function(e){return i(e,"previousSibling")},nextAll:function(e){return xe(e,"nextSibling")},prevAll:function(e){return xe(e,"previousSibling")},nextUntil:function(e,t,n){return xe(e,"nextSibling",n)},prevUntil:function(e,t,n){return xe(e,"previousSibling",n)},siblings:function(e){return be((e.parentNode||{}).firstChild,e)},children:function(e){return be(e.firstChild)},contents:function(e){return pe.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:pe.merge([],e.childNodes)}},function(e,t){pe.fn[e]=function(n,r){var i=pe.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=pe.filter(r,i)),this.length>1&&(Ae[e]||(i=pe.uniqueSort(i)),Se.test(e)&&(i=i.reverse())),this.pushStack(i)}});var De=/\S+/g;pe.Callbacks=function(e){e="string"==typeof e?o(e):pe.extend({},e);var t,n,r,i,a=[],s=[],u=-1,l=function(){for(i=e.once,r=t=!0;s.length;u=-1)for(n=s.shift();++u-1;)a.splice(n,1),n<=u&&u--}),this},has:function(e){return e?pe.inArray(e,a)>-1:a.length>0},empty:function(){return a&&(a=[]),this},disable:function(){return i=s=[],a=n="",this},disabled:function(){return!a},lock:function(){return i=!0,n||c.disable(),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=n||[],n=[e,n.slice?n.slice():n],s.push(n),t||l()),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},pe.extend({Deferred:function(e){var t=[["resolve","done",pe.Callbacks("once memory"),"resolved"],["reject","fail",pe.Callbacks("once memory"),"rejected"],["notify","progress",pe.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return pe.Deferred(function(n){pe.each(t,function(t,o){var a=pe.isFunction(e[t])&&e[t];i[o[1]](function(){var e=a&&a.apply(this,arguments);e&&pe.isFunction(e.promise)?e.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[o[0]+"With"](this===r?n.promise():this,a?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?pe.extend(e,r):r}},i={};return r.pipe=r.then,pe.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t,n,r,i=0,o=ie.call(arguments),a=o.length,s=1!==a||e&&pe.isFunction(e.promise)?a:0,u=1===s?e:pe.Deferred(),l=function(e,n,r){return function(i){n[e]=this,r[e]=arguments.length>1?ie.call(arguments):i,r===t?u.notifyWith(n,r):--s||u.resolveWith(n,r)}};if(a>1)for(t=new Array(a),n=new Array(a),r=new Array(a);i0||(je.resolveWith(re,[pe]),pe.fn.triggerHandler&&(pe(re).triggerHandler("ready"),pe(re).off("ready"))))}}),pe.ready.promise=function(t){if(!je)if(je=pe.Deferred(),"complete"===re.readyState||"loading"!==re.readyState&&!re.documentElement.doScroll)e.setTimeout(pe.ready);else if(re.addEventListener)re.addEventListener("DOMContentLoaded",s),e.addEventListener("load",s);else{re.attachEvent("onreadystatechange",s),e.attachEvent("onload",s);var n=!1;try{n=null==e.frameElement&&re.documentElement}catch(r){}n&&n.doScroll&&!function i(){if(!pe.isReady){try{n.doScroll("left")}catch(t){return e.setTimeout(i,50)}a(),pe.ready()}}()}return je.promise(t)},pe.ready.promise();var Le;for(Le in pe(fe))break;fe.ownFirst="0"===Le,fe.inlineBlockNeedsLayout=!1,pe(function(){var e,t,n,r;n=re.getElementsByTagName("body")[0],n&&n.style&&(t=re.createElement("div"),r=re.createElement("div"),r.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",n.appendChild(r).appendChild(t),"undefined"!=typeof t.style.zoom&&(t.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",fe.inlineBlockNeedsLayout=e=3===t.offsetWidth,e&&(n.style.zoom=1)),n.removeChild(r))}),function(){var e=re.createElement("div");fe.deleteExpando=!0;try{delete e.test}catch(t){fe.deleteExpando=!1}e=null}();var He=function(e){var t=pe.noData[(e.nodeName+" ").toLowerCase()],n=+e.nodeType||1;return(1===n||9===n)&&(!t||t!==!0&&e.getAttribute("classid")===t)},qe=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,_e=/([A-Z])/g;pe.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return e=e.nodeType?pe.cache[e[pe.expando]]:e[pe.expando],!!e&&!l(e)},data:function(e,t,n){return c(e,t,n)},removeData:function(e,t){return f(e,t)},_data:function(e,t,n){return c(e,t,n,!0)},_removeData:function(e,t){return f(e,t,!0)}}),pe.fn.extend({data:function(e,t){var n,r,i,o=this[0],a=o&&o.attributes;if(void 0===e){if(this.length&&(i=pe.data(o),1===o.nodeType&&!pe._data(o,"parsedAttrs"))){for(n=a.length;n--;)a[n]&&(r=a[n].name,0===r.indexOf("data-")&&(r=pe.camelCase(r.slice(5)),u(o,r,i[r])));pe._data(o,"parsedAttrs",!0)}return i}return"object"==typeof e?this.each(function(){pe.data(this,e)}):arguments.length>1?this.each(function(){pe.data(this,e,t)}):o?u(o,e,pe.data(o,e)):void 0},removeData:function(e){return this.each(function(){pe.removeData(this,e)})}}),pe.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=pe._data(e,t),n&&(!r||pe.isArray(n)?r=pe._data(e,t,pe.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=pe.queue(e,t),r=n.length,i=n.shift(),o=pe._queueHooks(e,t),a=function(){pe.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return pe._data(e,n)||pe._data(e,n,{empty:pe.Callbacks("once memory").add(function(){pe._removeData(e,t+"queue"),pe._removeData(e,n)})})}}),pe.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.lengtha",fe.leadingWhitespace=3===e.firstChild.nodeType,fe.tbody=!e.getElementsByTagName("tbody").length,fe.htmlSerialize=!!e.getElementsByTagName("link").length,fe.html5Clone="<:nav>"!==re.createElement("nav").cloneNode(!0).outerHTML,n.type="checkbox",n.checked=!0,t.appendChild(n),fe.appendChecked=n.checked,e.innerHTML="",fe.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue,t.appendChild(e),n=re.createElement("input"),n.setAttribute("type","radio"),n.setAttribute("checked","checked"),n.setAttribute("name","t"),e.appendChild(n),fe.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,fe.noCloneEvent=!!e.addEventListener,e[pe.expando]=1,fe.attributes=!e.getAttribute(pe.expando)}();var Xe={option:[1,""],legend:[1,""],area:[1,""],param:[1,""],thead:[1,""],tr:[2,""],col:[2,""],td:[3,""],_default:fe.htmlSerialize?[0,"",""]:[1,"X","
"]};Xe.optgroup=Xe.option,Xe.tbody=Xe.tfoot=Xe.colgroup=Xe.caption=Xe.thead,Xe.th=Xe.td;var Ue=/<|?\w+;/,Ve=/-1&&(h=p.split("."),p=h.shift(),h.sort()),a=p.indexOf(":")<0&&"on"+p,t=t[pe.expando]?t:new pe.Event(p,"object"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=h.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=r),n=null==n?[t]:pe.makeArray(n,[t]),l=pe.event.special[p]||{},i||!l.trigger||l.trigger.apply(r,n)!==!1)){if(!i&&!l.noBubble&&!pe.isWindow(r)){for(u=l.delegateType||p,Ke.test(u+p)||(s=s.parentNode);s;s=s.parentNode)d.push(s),c=s;c===(r.ownerDocument||re)&&d.push(c.defaultView||c.parentWindow||e)}for(f=0;(s=d[f++])&&!t.isPropagationStopped();)t.type=f>1?u:l.bindType||p,o=(pe._data(s,"events")||{})[t.type]&&pe._data(s,"handle"),o&&o.apply(s,n),o=a&&s[a],o&&o.apply&&He(s)&&(t.result=o.apply(s,n),t.result===!1&&t.preventDefault());if(t.type=p,!i&&!t.isDefaultPrevented()&&(!l._default||l._default.apply(d.pop(),n)===!1)&&He(r)&&a&&r[p]&&!pe.isWindow(r)){c=r[a],c&&(r[a]=null),pe.event.triggered=p;try{r[p]()}catch(g){}pe.event.triggered=void 0,c&&(r[a]=c)}return t.result}},dispatch:function(e){e=pe.event.fix(e);var t,n,r,i,o,a=[],s=ie.call(arguments),u=(pe._data(this,"events")||{})[e.type]||[],l=pe.event.special[e.type]||{};if(s[0]=e,e.delegateTarget=this,!l.preDispatch||l.preDispatch.call(this,e)!==!1){for(a=pe.event.handlers.call(this,e,u),t=0;(i=a[t++])&&!e.isPropagationStopped();)for(e.currentTarget=i.elem,n=0;(o=i.handlers[n++])&&!e.isImmediatePropagationStopped();)e.rnamespace&&!e.rnamespace.test(o.namespace)||(e.handleObj=o,e.data=o.data,r=((pe.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s),void 0!==r&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()));return l.postDispatch&&l.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,r,i,o,a=[],s=t.delegateCount,u=e.target;if(s&&u.nodeType&&("click"!==e.type||isNaN(e.button)||e.button<1))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||"click"!==e.type)){for(r=[],n=0;n-1:pe.find(i,this,null,[u]).length),r[i]&&r.push(o);r.length&&a.push({elem:u,handlers:r})}return s]","i"),tt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,nt=/
+
+
+
+
+
+
+
+