diff --git a/cmd/web.go b/cmd/web.go index 61e6d61..18c32a8 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -159,6 +159,9 @@ func runWeb(cliCtx *cli.Context) { m.Group("/app", func() { m.Combo("/list").Get(web.AppsGet) + m.Combo("/add").Post(bindIgnErr(forms.AppAddForm{}), web.AppAdd) + m.Get("/detail/:appName/collaborators", web.AppCollaboratorsGet) + m.Get("/detail/:appName/deployments", web.AppDeploymentsGet) }, reqSignIn) m.Group("/access_key", func() { diff --git a/core/clientService/client_service.go b/core/clientService/client_service.go index 37247fb..8b4d000 100644 --- a/core/clientService/client_service.go +++ b/core/clientService/client_service.go @@ -72,7 +72,7 @@ func UpdateCheck(cache cache.Cache, deploymentKey, appVersion, label, packageHas checkResult.PackageSize = pkg.Size pkgDiff := &model.PackageDiff{ - PackageID: pkg.ID, + OriginalPackageHash: pkg.Hash, DiffAgainstPackageHash: packageHash, } diff --git a/core/collaboratorService/collaborator_service.go b/core/collaboratorService/collaborator_service.go index a55ffae..cecd5aa 100644 --- a/core/collaboratorService/collaborator_service.go +++ b/core/collaboratorService/collaborator_service.go @@ -3,48 +3,18 @@ package collaboratorService import ( "errors" - . "gopkg.in/ahmetb/go-linq.v3" - . "github.com/MessageDream/goby/core" "github.com/MessageDream/goby/model" - "github.com/MessageDream/goby/model/dto" "github.com/MessageDream/goby/module/infrastructure" ) -func List(uid uint64, appName string) (map[string]*dto.Collaborator, error) { +func List(uid uint64, appName string) ([]*model.Collaborator, error) { col, err := CollaboratorOf(uid, appName) if err != nil { return nil, err } - cols, err := model.FindCollaboratorsByAppIDs([]uint64{col.AppID}) - if err != nil { - return nil, err - } - - canOwner := false - colsMap := map[string]*dto.Collaborator{} - From(cols).Select(func(col interface{}) interface{} { - co := col.(*model.Collaborator) - isOwner := uid == co.UID - if isOwner && co.Role == 1 { - canOwner = true - } - permission := "Member" - if co.Role == 1 { - permission = "Owner" - } - return KeyValue{ - Key: co.Email, - Value: &dto.Collaborator{ - IsCurrentAccount: isOwner, - Permission: permission, - }, - } - - }).ToMap(&colsMap) - - return colsMap, nil + return model.FindCollaboratorsByAppIDs([]uint64{col.AppID}) } diff --git a/core/core.go b/core/core.go index c888cdd..9744bd9 100644 --- a/core/core.go +++ b/core/core.go @@ -28,6 +28,17 @@ func OwnerCan(uid uint64, name string) (*model.Collaborator, error) { return col, nil } +func OwnerOf(name string) (*model.Collaborator, error) { + col, err := model.FindOwnerByAppName(name) + if err != nil || col == nil { + if err != nil { + return nil, err + } + return nil, ErrAppNotExist + } + return col, nil +} + func CollaboratorOf(uid uint64, name string) (*model.Collaborator, error) { col, err := model.FindCollaboratorByAppNameAndUID(name, uid) diff --git a/core/deploymentService/deployment_service.go b/core/deploymentService/deployment_service.go index 7e84aa4..7d75970 100644 --- a/core/deploymentService/deployment_service.go +++ b/core/deploymentService/deployment_service.go @@ -5,7 +5,6 @@ import ( "io" "os" "path" - "strconv" "strings" "github.com/go-macaron/cache" @@ -274,7 +273,7 @@ func ReleaseDeployment(user *model.User, manifesURLPath, zipURLPath, "Upload", - strconv.FormatUint(user.ID, 10)+"&"+user.Email, + user.Email, description, "", "") @@ -507,7 +506,7 @@ func RollbackDeployment(user *model.User, cache cache.Cache, appName, deployment DeployVersionID: version.ID, } - pkgs, err := rollbackPkg.FindPackagesByVersionIDAndReleaseMethods([]string{"Upload", "Promote"}, 2, false) + pkgs, err := rollbackPkg.FindPackagesByVersionIDAndReleaseMethods(2, false, "Upload", "Promote") if err != nil { return err } @@ -536,15 +535,16 @@ func RollbackDeployment(user *model.User, cache cache.Cache, appName, deployment rollbackPkg.ManifestBlobURL, rollbackPkg.BlobURL, "Rollback", - strconv.FormatUint(user.ID, 10)+"&"+user.Email, + user.Email, rollbackPkg.Description, rollbackPkg.Label, deployment.Name) if err != nil { - clearCache(cache, deployment.Key, version.AppVersion) + return err } - return err + clearCache(cache, deployment.Key, version.AppVersion) + return nil } func PromoteDeployment(user *model.User, cache cache.Cache, appName, sourceDeploymentName, destDeploymentName string) error { @@ -599,7 +599,7 @@ func PromoteDeployment(user *model.User, cache cache.Cache, appName, sourceDeplo sourcePkg.ManifestBlobURL, sourcePkg.BlobURL, "Promote", - strconv.FormatUint(user.ID, 10)+"&"+user.Email, + user.Email, sourcePkg.Description, sourcePkg.Label, sourceDeployment.Name) diff --git a/core/deploymentService/package_service.go b/core/deploymentService/package_service.go index a4a85cf..f9f2b16 100644 --- a/core/deploymentService/package_service.go +++ b/core/deploymentService/package_service.go @@ -193,10 +193,12 @@ func createPackage(deployment *model.Deployment, } if exist, err := pkgCheck.Exist(); err != nil || exist { - if exist { + if err != nil { + return nil, err + } + if exist && releaseMethod != "Rollback" { return nil, ErrDeploymentPackageAlreadyExist } - return nil, err } result, err := model.Transaction(func(sess *xorm.Session) (interface{}, error) { @@ -316,7 +318,7 @@ func createDiffPackage(originalPackage *model.Package) ([]*model.PackageDiff, er func createOneDiffPackage(originalPackage, prePackage *model.Package) (*model.PackageDiff, error) { pkgDiff := &model.PackageDiff{ - PackageID: originalPackage.ID, + OriginalPackageHash: originalPackage.Hash, DiffAgainstPackageHash: prePackage.Hash, } @@ -474,7 +476,7 @@ func createOneDiffPackage(originalPackage, prePackage *model.Package) (*model.Pa }() diffPkg := &model.PackageDiff{ - PackageID: originalPackage.ID, + OriginalPackageHash: originalPackage.Hash, DiffAgainstPackageHash: prePackage.Hash, DiffBlobURL: zipURLPath, DiffSize: diffSize, diff --git a/model/collaborator.go b/model/collaborator.go index b9e6f97..2783dea 100644 --- a/model/collaborator.go +++ b/model/collaborator.go @@ -75,13 +75,31 @@ func FindCollaboratorsByAppIDs(appIds []uint64) ([]*Collaborator, error) { return cols, x.In("app_id", appIds).Find(&cols) } +func FindOwnerByAppName(appName string) (*Collaborator, error) { + col := &Collaborator{} + + exsit, err := x.Sql(`SELECT b.* FROM app AS a + INNER JOIN collaborator AS b + ON a.id = b.app_id + WHERE a.name = ? AND b.Role = 1 AND a.deleted_at IS NULL AND b.deleted_at IS NULL + LIMIT 1`, appName).Get(col) + + if err != nil { + return nil, err + } + if !exsit { + return nil, nil + } + return col, nil +} + func FindCollaboratorByAppNameAndUID(appName string, uid uint64) (*Collaborator, error) { col := &Collaborator{} exsit, err := x.Sql(`SELECT b.* FROM app AS a INNER JOIN collaborator AS b ON a.id = b.app_id - WHERE a.name = ? and b.uid = ? AND a.deleted_at IS NULL AND b.deleted_at IS NULL + WHERE a.name = ? AND b.uid = ? AND a.deleted_at IS NULL AND b.deleted_at IS NULL LIMIT 1`, appName, uid).Get(col) if err != nil { diff --git a/model/deployment.go b/model/deployment.go index 7ba7b4a..a50e642 100644 --- a/model/deployment.go +++ b/model/deployment.go @@ -36,10 +36,21 @@ func (self *DeploymentDetail) Convert() interface{} { UploadTime: self.Package.CreatedAt.Unix() * 1000, } } + + var metrics *dto.PackageMetrics + if self.PackageMetrics.ID > 0 { + metrics = &dto.PackageMetrics{ + Active: self.PackageMetrics.Active, + Downloaded: self.PackageMetrics.Downloaded, + Failed: self.PackageMetrics.Failed, + Installed: self.PackageMetrics.Installed, + } + } return &dto.Deployment{ - Key: self.Key, - Name: self.Name, - Package: pkg, + Key: self.Key, + Name: self.Name, + Package: pkg, + PackageMetrics: metrics, } } diff --git a/model/dto/dto_deployment.go b/model/dto/dto_deployment.go index ca4a0ce..39247bd 100644 --- a/model/dto/dto_deployment.go +++ b/model/dto/dto_deployment.go @@ -1,7 +1,8 @@ package dto type Deployment struct { - Key string `json:"key"` - Name string `json:"name"` - Package *Package `json:"package"` + Key string `json:"key"` + Name string `json:"name"` + Package *Package `json:"package"` + PackageMetrics *PackageMetrics `json:packageMetrics` } diff --git a/model/dto/dto_package.go b/model/dto/dto_package.go index 483729b..c3af14f 100644 --- a/model/dto/dto_package.go +++ b/model/dto/dto_package.go @@ -28,10 +28,11 @@ type Package struct { } type PackageMetrics struct { - Active uint64 `json:"active"` - Downloaded uint64 `json:"downloaded"` - Failed uint64 `json:"failed"` - Installed uint64 `json:"installed"` + Active uint64 `json:"active"` + TotalActive uint64 `json:"totalActive"` + Downloaded uint64 `json:"downloaded"` + Failed uint64 `json:"failed"` + Installed uint64 `json:"installed"` } type UpdatePackageInfo struct { diff --git a/model/package.go b/model/package.go index 73f6c59..0b569e4 100644 --- a/model/package.go +++ b/model/package.go @@ -74,10 +74,10 @@ func (self *Package) FindPrePackages(number int, isAsc bool) ([]*Package, error) } -func (self *Package) FindPackagesByVersionIDAndReleaseMethods(methods []string, number int, isAsc bool) ([]*Package, error) { +func (self *Package) FindPackagesByVersionIDAndReleaseMethods(number int, isAsc bool, methods ...string) ([]*Package, error) { packages := make([]*Package, 0, number) - sess := x.Where("deploy_version_id = ?", self.DeployVersionID).In("release_method", &methods) + sess := x.Where("deploy_version_id = ?", self.DeployVersionID).In("release_method", methods) if isAsc { sess = sess.Asc("id") } else { @@ -92,7 +92,7 @@ func (self *Package) FindPackagesByVersionIDAndReleaseMethods(methods []string, type PackageDiff struct { ID uint64 `xorm:"pk autoincr"` - PackageID uint64 `xorm:"notnull default(0)"` + OriginalPackageHash string DiffAgainstPackageHash string DiffBlobURL string DiffSize int64 `xorm:"notnull default(0)"` @@ -106,7 +106,7 @@ func (self *PackageDiff) Update(engine Engine, specFields ...string) error { } func (self *PackageDiff) Exist() (bool, error) { - exi, err := x.Where("id!=?", 0).Get(&PackageDiff{PackageID: self.PackageID, DiffAgainstPackageHash: self.DiffAgainstPackageHash}) + exi, err := x.Where("id!=?", 0).Get(&PackageDiff{OriginalPackageHash: self.OriginalPackageHash, DiffAgainstPackageHash: self.DiffAgainstPackageHash}) return exi, err } diff --git a/model/user.go b/model/user.go index dea0feb..a645bc5 100644 --- a/model/user.go +++ b/model/user.go @@ -52,7 +52,7 @@ func (self *User) GenerateSalt() { func (self *User) Tokens() ([]*UserToken, error) { tokens := make([]*UserToken, 0, 10) - err := x.Find(&tokens, &UserToken{UID: self.ID}) + err := x.Desc("created_at").Find(&tokens, &UserToken{UID: self.ID}) return tokens, err } diff --git a/module/context/html_context.go b/module/context/html_context.go index e7009fe..ddbf23c 100644 --- a/module/context/html_context.go +++ b/module/context/html_context.go @@ -110,23 +110,23 @@ func HTMLContexter() macaron.Handler { Session: sess, } + ctx.Auth() + link := ctx.Req.RequestURI i := strings.Index(link, "?") if i > -1 { link = link[:i] } ctx.Data["Link"] = link - ctx.Data["PageStartTime"] = time.Now() + ctx.Data["ShowRegistrationButton"] = !disableRegistration + csrfToken := x.GetToken() + ctx.Data["CsrfToken"] = csrfToken + ctx.Data["CsrfTokenHtml"] = template.HTML(``) - ctx.Auth() - - ctx.Data["CsrfToken"] = x.GetToken() - ctx.Data["CsrfTokenHtml"] = template.HTML(``) log.Trace("Session ID: %s", sess.ID()) - log.Trace("CSRF Token: %v", ctx.Data["CsrfToken"]) + log.Trace("CSRF Token: %v", csrfToken) - ctx.Data["ShowRegistrationButton"] = !disableRegistration c.Map(ctx) } } diff --git a/module/form/app_form.go b/module/form/app_form.go new file mode 100644 index 0000000..ceba985 --- /dev/null +++ b/module/form/app_form.go @@ -0,0 +1,15 @@ +package form + +import ( + "github.com/go-macaron/binding" + macaron "gopkg.in/macaron.v1" +) + +type AppAddForm struct { + Name string `form:"name" binding:"Required;MaxSize(35)"` + Platform string `form:"platform" binding:"Required"` +} + +func (f *AppAddForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { + return validate(errs, ctx.Data, f) +} diff --git a/module/infrastructure/tool.go b/module/infrastructure/tool.go index 4874d16..73cee0d 100644 --- a/module/infrastructure/tool.go +++ b/module/infrastructure/tool.go @@ -253,7 +253,11 @@ func timeSince(then time.Time) string { case diff <= 2: return fmt.Sprintf("1 秒%s", lbl) case diff < 1*Minute: - return fmt.Sprintf("tool.seconds", diff, lbl) + se := float64(diff) / 1000 + if se < 0.1 { + se = 0.1 + } + return fmt.Sprintf("%.1f 秒%s", se, lbl) case diff < 2*Minute: return fmt.Sprintf("1 分钟%s", lbl) @@ -589,6 +593,13 @@ func DeCompress(zipFile, dest string) error { } defer rc.Close() filename := path.Join(dest, file.Name) + if file.FileInfo().IsDir() { + err = os.MkdirAll(filename, 0755) + if err != nil { + return err + } + continue + } err = os.MkdirAll(getDir(filename), 0755) if err != nil { return err diff --git a/module/template/template.go b/module/template/template.go index 5c64fb3..4d03d24 100644 --- a/module/template/template.go +++ b/module/template/template.go @@ -99,15 +99,24 @@ func NewFuncMap() []template.FuncMap { }, "FileSize": infrastructure.FileSize, "Subtract": infrastructure.Subtract, - "Add": func(a, b int) int { + "Add": func(a, b uint64) uint64 { return a + b }, + "Persent": func(a, b uint64) string { + if b == 0 { + return "0" + } + return fmt.Sprintf("%.1f", float32(a)/float32(b)*100) + }, "DateFmtLong": func(t time.Time) string { return t.Format(time.RFC1123Z) }, "DateFmtShort": func(t time.Time) string { return t.Format("Jan 02, 2006") }, + "Time": func(interval int64) time.Time { + return time.Unix(interval/1000, interval) + }, "List": List, "SubStr": func(str string, start, length int) string { if len(str) == 0 { diff --git a/public/assets/octicons-4.3.0/octicons.eot b/public/assets/octicons-4.3.0/octicons.eot deleted file mode 100755 index b4c7a98..0000000 Binary files a/public/assets/octicons-4.3.0/octicons.eot and /dev/null differ diff --git a/public/assets/octicons-4.3.0/octicons.min.css b/public/assets/octicons-4.3.0/octicons.min.css deleted file mode 100755 index a000669..0000000 --- a/public/assets/octicons-4.3.0/octicons.min.css +++ /dev/null @@ -1 +0,0 @@ -@font-face{font-family:Octicons;src:url(octicons.eot?ef21c39f0ca9b1b5116e5eb7ac5eabe6);src:url(octicons.eot?#iefix) format("embedded-opentype"),url(octicons.woff2?ef21c39f0ca9b1b5116e5eb7ac5eabe6) format("woff2"),url(octicons.woff?ef21c39f0ca9b1b5116e5eb7ac5eabe6) format("woff"),url(octicons.ttf?ef21c39f0ca9b1b5116e5eb7ac5eabe6) format("truetype"),url(octicons.svg?ef21c39f0ca9b1b5116e5eb7ac5eabe6#octicons) format("svg");font-weight:400;font-style:normal}.mega-octicon,.octicon{font:normal normal normal 16px/1 Octicons;display:inline-block;text-decoration:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-user-select:none;-ms-user-select:none;user-select:none;speak:none}.mega-octicon{font-size:32px}.octicon-alert:before{content:"\f02d"}.octicon-arrow-down:before{content:"\f03f"}.octicon-arrow-left:before{content:"\f040"}.octicon-arrow-right:before{content:"\f03e"}.octicon-arrow-small-down:before{content:"\f0a0"}.octicon-arrow-small-left:before{content:"\f0a1"}.octicon-arrow-small-right:before{content:"\f071"}.octicon-arrow-small-up:before{content:"\f09f"}.octicon-arrow-up:before{content:"\f03d"}.octicon-beaker:before{content:"\f0dd"}.octicon-bell:before{content:"\f0de"}.octicon-bold:before{content:"\f0e2"}.octicon-book:before{content:"\f007"}.octicon-bookmark:before{content:"\f07b"}.octicon-briefcase:before{content:"\f0d3"}.octicon-broadcast:before{content:"\f048"}.octicon-browser:before{content:"\f0c5"}.octicon-bug:before{content:"\f091"}.octicon-calendar:before{content:"\f068"}.octicon-check:before{content:"\f03a"}.octicon-checklist:before{content:"\f076"}.octicon-chevron-down:before{content:"\f0a3"}.octicon-chevron-left:before{content:"\f0a4"}.octicon-chevron-right:before{content:"\f078"}.octicon-chevron-up:before{content:"\f0a2"}.octicon-circle-slash:before{content:"\f084"}.octicon-circuit-board:before{content:"\f0d6"}.octicon-clippy:before{content:"\f035"}.octicon-clock:before{content:"\f046"}.octicon-cloud-download:before{content:"\f00b"}.octicon-cloud-upload:before{content:"\f00c"}.octicon-code:before{content:"\f05f"}.octicon-comment-discussion:before{content:"\f04f"}.octicon-comment:before{content:"\f02b"}.octicon-credit-card:before{content:"\f045"}.octicon-dash:before{content:"\f0ca"}.octicon-dashboard:before{content:"\f07d"}.octicon-database:before{content:"\f096"}.octicon-desktop-download:before{content:"\f0dc"}.octicon-device-camera-video:before{content:"\f057"}.octicon-device-camera:before{content:"\f056"}.octicon-device-desktop:before{content:"\f27c"}.octicon-device-mobile:before{content:"\f038"}.octicon-diff-added:before{content:"\f06b"}.octicon-diff-ignored:before{content:"\f099"}.octicon-diff-modified:before{content:"\f06d"}.octicon-diff-removed:before{content:"\f06c"}.octicon-diff-renamed:before{content:"\f06e"}.octicon-diff:before{content:"\f04d"}.octicon-ellipses:before{content:"\f101"}.octicon-ellipsis:before{content:"\f09a"}.octicon-eye:before{content:"\f04e"}.octicon-file-binary:before{content:"\f094"}.octicon-file-code:before{content:"\f010"}.octicon-file-directory:before{content:"\f016"}.octicon-file-media:before{content:"\f012"}.octicon-file-pdf:before{content:"\f014"}.octicon-file-submodule:before{content:"\f017"}.octicon-file-symlink-directory:before{content:"\f0b1"}.octicon-file-symlink-file:before{content:"\f0b0"}.octicon-file-text:before{content:"\f011"}.octicon-file-zip:before{content:"\f013"}.octicon-file:before{content:"\f102"}.octicon-flame:before{content:"\f0d2"}.octicon-fold:before{content:"\f0cc"}.octicon-gear:before{content:"\f02f"}.octicon-gift:before{content:"\f042"}.octicon-gist-secret:before{content:"\f08c"}.octicon-gist:before{content:"\f00e"}.octicon-git-branch:before{content:"\f020"}.octicon-git-commit:before{content:"\f01f"}.octicon-git-compare:before{content:"\f0ac"}.octicon-git-merge:before{content:"\f023"}.octicon-git-pull-request:before{content:"\f009"}.octicon-globe:before{content:"\f0b6"}.octicon-grabber:before{content:"\f103"}.octicon-graph:before{content:"\f043"}.octicon-heart:before{content:"\2665"}.octicon-history:before{content:"\f07e"}.octicon-home:before{content:"\f08d"}.octicon-horizontal-rule:before{content:"\f070"}.octicon-hubot:before{content:"\f09d"}.octicon-inbox:before{content:"\f0cf"}.octicon-info:before{content:"\f059"}.octicon-issue-closed:before{content:"\f028"}.octicon-issue-opened:before{content:"\f026"}.octicon-issue-reopened:before{content:"\f027"}.octicon-italic:before{content:"\f0e4"}.octicon-jersey:before{content:"\f019"}.octicon-key:before{content:"\f049"}.octicon-keyboard:before{content:"\f00d"}.octicon-law:before{content:"\f0d8"}.octicon-light-bulb:before{content:"\f000"}.octicon-link-external:before{content:"\f07f"}.octicon-link:before{content:"\f05c"}.octicon-list-ordered:before{content:"\f062"}.octicon-list-unordered:before{content:"\f061"}.octicon-location:before{content:"\f060"}.octicon-lock:before{content:"\f06a"}.octicon-logo-gist:before{content:"\f0ad"}.octicon-logo-github:before{content:"\f092"}.octicon-mail-read:before{content:"\f03c"}.octicon-mail-reply:before{content:"\f051"}.octicon-mail:before{content:"\f03b"}.octicon-mark-github:before{content:"\f00a"}.octicon-markdown:before{content:"\f0c9"}.octicon-megaphone:before{content:"\f077"}.octicon-mention:before{content:"\f0be"}.octicon-milestone:before{content:"\f075"}.octicon-mirror:before{content:"\f024"}.octicon-mortar-board:before{content:"\f0d7"}.octicon-mute:before{content:"\f080"}.octicon-no-newline:before{content:"\f09c"}.octicon-octoface:before{content:"\f008"}.octicon-organization:before{content:"\f037"}.octicon-package:before{content:"\f0c4"}.octicon-paintcan:before{content:"\f0d1"}.octicon-pencil:before{content:"\f058"}.octicon-person:before{content:"\f018"}.octicon-pin:before{content:"\f041"}.octicon-plug:before{content:"\f0d4"}.octicon-plus-small:before{content:"\f104"}.octicon-plus:before{content:"\f05d"}.octicon-primitive-dot:before{content:"\f052"}.octicon-primitive-square:before{content:"\f053"}.octicon-pulse:before{content:"\f085"}.octicon-question:before{content:"\f02c"}.octicon-quote:before{content:"\f063"}.octicon-radio-tower:before{content:"\f030"}.octicon-reply:before{content:"\f105"}.octicon-repo-clone:before{content:"\f04c"}.octicon-repo-force-push:before{content:"\f04a"}.octicon-repo-forked:before{content:"\f002"}.octicon-repo-pull:before{content:"\f006"}.octicon-repo-push:before{content:"\f005"}.octicon-repo:before{content:"\f001"}.octicon-rocket:before{content:"\f033"}.octicon-rss:before{content:"\f034"}.octicon-ruby:before{content:"\f047"}.octicon-search:before{content:"\f02e"}.octicon-server:before{content:"\f097"}.octicon-settings:before{content:"\f07c"}.octicon-shield:before{content:"\f0e1"}.octicon-sign-in:before{content:"\f036"}.octicon-sign-out:before{content:"\f032"}.octicon-smiley:before{content:"\f0e7"}.octicon-squirrel:before{content:"\f0b2"}.octicon-star:before{content:"\f02a"}.octicon-stop:before{content:"\f08f"}.octicon-sync:before{content:"\f087"}.octicon-tag:before{content:"\f015"}.octicon-tasklist:before{content:"\f0e5"}.octicon-telescope:before{content:"\f088"}.octicon-terminal:before{content:"\f0c8"}.octicon-text-size:before{content:"\f0e3"}.octicon-three-bars:before{content:"\f05e"}.octicon-thumbsdown:before{content:"\f0db"}.octicon-thumbsup:before{content:"\f0da"}.octicon-tools:before{content:"\f031"}.octicon-trashcan:before{content:"\f0d0"}.octicon-triangle-down:before{content:"\f05b"}.octicon-triangle-left:before{content:"\f044"}.octicon-triangle-right:before{content:"\f05a"}.octicon-triangle-up:before{content:"\f0aa"}.octicon-unfold:before{content:"\f039"}.octicon-unmute:before{content:"\f0ba"}.octicon-unverified:before{content:"\f0e8"}.octicon-verified:before{content:"\f0e6"}.octicon-versions:before{content:"\f064"}.octicon-watch:before{content:"\f0e0"}.octicon-x:before{content:"\f081"}.octicon-zap:before{content:"\26a1"} \ No newline at end of file diff --git a/public/assets/octicons-4.3.0/octicons.svg b/public/assets/octicons-4.3.0/octicons.svg deleted file mode 100755 index 41cbd3f..0000000 --- a/public/assets/octicons-4.3.0/octicons.svg +++ /dev/null @@ -1,429 +0,0 @@ - - - - -Created by FontForge 20150913 at Mon Jul 11 12:02:11 2016 - By Aaron Shekey - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/assets/octicons-4.3.0/octicons.ttf b/public/assets/octicons-4.3.0/octicons.ttf deleted file mode 100755 index ff0dda1..0000000 Binary files a/public/assets/octicons-4.3.0/octicons.ttf and /dev/null differ diff --git a/public/assets/octicons-4.3.0/octicons.woff b/public/assets/octicons-4.3.0/octicons.woff deleted file mode 100755 index 01aa43d..0000000 Binary files a/public/assets/octicons-4.3.0/octicons.woff and /dev/null differ diff --git a/public/assets/octicons-4.3.0/octicons.woff2 b/public/assets/octicons-4.3.0/octicons.woff2 deleted file mode 100755 index 69e7b2a..0000000 Binary files a/public/assets/octicons-4.3.0/octicons.woff2 and /dev/null differ diff --git a/public/css/extra_colors.css b/public/css/extra_colors.css new file mode 100644 index 0000000..e3a0628 --- /dev/null +++ b/public/css/extra_colors.css @@ -0,0 +1,404 @@ +/* =============Extra Segment and Tooltip Color============= */ +.nightli { + background: #2e3e4e; + color: #fff; + text-shadow: none !important; + background-image: none !important; +} + +.ui.inverted.nightli.bottom.popup:before, +.ui.inverted.nightli.left.center.popup:before, +.ui.inverted.nightli.right.center.popup:before, +.ui.inverted.nightli.top.popup:before { + background: #2e3e4e !important; +} + +.whiteli { + background: #fff !important; + color: #2e3e4e !important; + text-shadow: none !important; + background-image: none !important; +} + +.ui.inverted.whiteli.bottom.popup:before, +.ui.inverted.whiteli.left.center.popup:before, +.ui.inverted.whiteli.right.center.popup:before, +.ui.inverted.whiteli.top.popup:before { + background: #fff; +} + +.redli { + background: #F25F5C !important; + color: #fff !important; + text-shadow: none !important; + background-image: none !important; +} + +.ui.inverted.redli.bottom.popup:before, +.ui.inverted.redli.left.center.popup:before, +.ui.inverted.redli.right.center.popup:before, +.ui.inverted.redli.top.popup:before { + background: #F25F5C; +} + +.blueli { + background: #247BA0 !important; + color: #fff !important; + text-shadow: none !important; + background-image: none !important; +} + +.ui.inverted.blueli.bottom.popup:before, +.ui.inverted.blueli.left.center.popup:before, +.ui.inverted.blueli.right.center.popup:before, +.ui.inverted.blueli.top.popup:before { + background: #247BA0; +} + +.yellowli { + background: #FFE066 !important; + color: #50514F !important; + text-shadow: none !important; + background-image: none !important; +} + +.ui.inverted.yellowli.bottom.popup:before, +.ui.inverted.yellowli.left.center.popup:before, +.ui.inverted.yellowli.right.center.popup:before, +.ui.inverted.yellowli.top.popup:before { + background: #FFE066; +} + +.greyli { + background: #50514F !important; + color: #fff !important; + text-shadow: none !important; + background-image: none !important; +} + +.ui.inverted.greyli.bottom.popup:before, +.ui.inverted.greyli.left.center.popup:before, +.ui.inverted.greyli.right.center.popup:before, +.ui.inverted.greyli.top.popup:before { + background: #50514F; +} + +.greenli { + background: #32936F !important; + color: #fff !important; + text-shadow: none !important; + background-image: none !important; +} + +.ui.inverted.greenli.bottom.popup:before, +.ui.inverted.greenli.left.center.popup:before, +.ui.inverted.greenli.right.center.popup:before, +.ui.inverted.greenli.top.popup:before { + background: #32936F; +} + +.darkpurpleli { + background: #2A1A1F !important; + color: #fff !important; + text-shadow: none !important; + background-image: none !important; +} + +.ui.inverted.darkpurpleli.bottom.popup:before, +.ui.inverted.darkpurpleli.left.center.popup:before, +.ui.inverted.darkpurpleli.right.center.popup:before, +.ui.inverted.darkpurpleli.top.popup:before { + background: #2A1A1F; +} + +.darkorangeli { + background: #764134 !important; + color: #fff !important; + text-shadow: none !important; + background-image: none !important; +} + +.ui.inverted.darkorangeli.bottom.popup:before, +.ui.inverted.darkorangeli.left.center.popup:before, +.ui.inverted.darkorangeli.right.center.popup:before, +.ui.inverted.darkorangeli.top.popup:before { + background: #764134; +} + +.greenli2 { + background: #307473 !important; + color: #fff !important; + text-shadow: none !important; + background-image: none !important; +} + +.ui.inverted.greenli2.bottom.popup:before, +.ui.inverted.greenli2.left.center.popup:before, +.ui.inverted.greenli2.right.center.popup:before, +.ui.inverted.greenli2.top.popup:before { + background: #307473; +} + +.pinkli { + background: #E76D83 !important; + color: #fff !important; + text-shadow: none !important; + background-image: none !important; +} + +.ui.inverted.pinkli.bottom.popup:before, +.ui.inverted.pinkli.left.center.popup:before, +.ui.inverted.pinkli.right.center.popup:before, +.ui.inverted.pinkli.top.popup:before { + background: #E76D83; +} + +.lightyellowli { + background: #EFD28D !important; + color: #001011 !important; + text-shadow: none !important; + background-image: none !important; +} + +.ui.inverted.lightyellowli.bottom.popup:before, +.ui.inverted.lightyellowli.left.center.popup:before, +.ui.inverted.lightyellowli.right.center.popup:before, +.ui.inverted.lightyellowli.top.popup:before { + background: #EFD28D; +} + +.darkli { + background: #001011 !important; + color: #fff !important; + text-shadow: none !important; + background-image: none !important; +} + +.ui.inverted.darkli.bottom.popup:before, +.ui.inverted.darkli.left.center.popup:before, +.ui.inverted.darkli.right.center.popup:before, +.ui.inverted.darkli.top.popup:before { + background: #001011; +} + +.pinkli2 { + background: #C1839F !important; + color: #fff !important; + text-shadow: none !important; + background-image: none !important; +} + +.ui.inverted.pinkli2.bottom.popup:before, +.ui.inverted.pinkli2.left.center.popup:before, +.ui.inverted.pinkli2.right.center.popup:before, +.ui.inverted.pinkli2.top.popup:before { + background: #C1839F; +} + +.lightbrownli { + background: #E1B07E !important; + color: #fff !important; + text-shadow: none !important; + background-image: none !important; +} + +.ui.inverted.lightbrownli.bottom.popup:before, +.ui.inverted.lightbrownli.left.center.popup:before, +.ui.inverted.lightbrownli.right.center.popup:before, +.ui.inverted.lightbrownli.top.popup:before { + background: #E1B07E; +} +/* =============Extra Segment and Tooltip Color============= */ + +/* =============Extra Radio and Checkbox Color============= */ +.ui.toggle.checkbox input:checked ~ .box:before, +.ui.toggle.checkbox input:checked ~ .coloring.red:before { + background: #F25F5C !important; +} + +.ui.toggle.checkbox input:checked ~ .box:before, +.ui.toggle.checkbox input:checked ~ .coloring.yellow:before { + background: #EFD28D !important; +} + +.ui.toggle.checkbox input:checked ~ .box:before, +.ui.toggle.checkbox input:checked ~ .coloring.blue:before { + background: #247BA0 !important; +} + +.ui.toggle.checkbox input:checked ~ .box:before, +.ui.toggle.checkbox input:checked ~ .coloring.green:before { + background: #307473 !important; +} + +.ui.toggle.checkbox input:checked ~ .box:before, +.ui.toggle.checkbox input:checked ~ .coloring.black:before { + background: #001011 !important; +} + +.ui.toggle.checkbox input:checked ~ .box:before, +.ui.toggle.checkbox input:checked ~ .coloring.orange:before { + background: orange !important; +} + +.ui.toggle.checkbox input:checked ~ .box:before, +.ui.toggle.checkbox input:checked ~ .coloring.grey:before { + background: #666 !important; +} + +.ui.toggle.checkbox input:checked ~ .box:before, +.ui.toggle.checkbox input:checked ~ .coloring.pink:before { + background: #C1839F !important; +} + +.ui.toggle.checkbox input:checked ~ .box:before, +.ui.toggle.checkbox input:checked ~ .coloring.brown:before { + background: #764134 !important; +} + +.ui.slider.checkbox input:checked ~ .box:before, +.ui.slider.checkbox input:checked ~ .coloring.red:before { + background: #F25F5C !important; +} + +.ui.slider.checkbox input:checked ~ .box:before, +.ui.slider.checkbox input:checked ~ .coloring.yellow:before { + background: #EFD28D !important; +} + +.ui.slider.checkbox input:checked ~ .box:before, +.ui.slider.checkbox input:checked ~ .coloring.blue:before { + background: #247BA0 !important; +} + +.ui.slider.checkbox input:checked ~ .box:before, +.ui.slider.checkbox input:checked ~ .coloring.green:before { + background: #307473 !important; +} + +.ui.slider.checkbox input:checked ~ .box:before, +.ui.slider.checkbox input:checked ~ .coloring.black:before { + background: #001011 !important; +} + +.ui.slider.checkbox input:checked ~ .box:before, +.ui.slider.checkbox input:checked ~ .coloring.orange:before { + background: orange !important; +} + +.ui.slider.checkbox input:checked ~ .box:before, +.ui.slider.checkbox input:checked ~ .coloring.grey:before { + background: #666 !important; +} + +.ui.slider.checkbox input:checked ~ .box:before, +.ui.slider.checkbox input:checked ~ .coloring.pink:before { + background: #C1839F !important; +} + +.ui.slider.checkbox input:checked ~ .box:before, +.ui.slider.checkbox input:checked ~ .coloring.brown:before { + background: #764134 !important; +} + +.ui.radio.checkbox input:checked ~ .box:after, +.ui.radio.checkbox input:checked ~ .coloring.red:after { + background: #F25F5C !important; +} + +.ui.radio.checkbox input:checked ~ .box:after, +.ui.radio.checkbox input:checked ~ .coloring.yellow:after { + background: #EFD28D !important; +} + +.ui.radio.checkbox input:checked ~ .box:after, +.ui.radio.checkbox input:checked ~ .coloring.blue:after { + background: #247BA0 !important; +} + +.ui.radio.checkbox input:checked ~ .box:after, +.ui.radio.checkbox input:checked ~ .coloring.green:after { + background: #307473 !important; +} + +.ui.radio.checkbox input:checked ~ .box:after, +.ui.radio.checkbox input:checked ~ .coloring.orange:after { + background: orange !important; +} + +.ui.radio.checkbox input:checked ~ .box:after, +.ui.radio.checkbox input:checked ~ .coloring.grey:after { + background: #666 !important; +} + +.ui.radio.checkbox input:checked ~ .box:after, +.ui.radio.checkbox input:checked ~ .coloring.pink:after { + background: #C1839F !important; +} + +.ui.radio.checkbox input:checked ~ .box:after, +.ui.radio.checkbox input:checked ~ .coloring.brown:after { + background: #764134 !important; +} + +.ui.checkbox input:checked ~ .box:after, +.ui.checkbox input:checked ~ .coloring.red:after { + color: #F25F5C !important; +} + +.ui.checkbox input:checked ~ .box:after, +.ui.checkbox input:checked ~ .coloring.yellow:after { + color: #EFD28D !important; +} + +.ui.checkbox input:checked ~ .box:after, +.ui.checkbox input:checked ~ .coloring.blue:after { + color: #247BA0 !important; +} + +.ui.checkbox input:checked ~ .box:after, +.ui.checkbox input:checked ~ .coloring.green:after { + color: #307473 !important; +} + +.ui.checkbox input:checked ~ .box:after, +.ui.checkbox input:checked ~ .coloring.orange:after { + color: orange !important; +} + +.ui.checkbox input:checked ~ .box:after, +.ui.checkbox input:checked ~ .coloring.grey:after { + color: #666 !important; +} + +.ui.checkbox input:checked ~ .box:after, +.ui.checkbox input:checked ~ .coloring.pink:after { + color: #C1839F !important; +} + +.ui.checkbox input:checked ~ .box:after, +.ui.checkbox input:checked ~ .coloring.brown:after { + color: #764134 !important; +} +.text-default{ + color: #000; +} +.text-primary{ + color: blue; +} +.text-warning{ +color:#DC851F; +} +.text-error{ + color: #F25F5C; +} +.text-success{ + color: #32936F; +} +.text-info{ + color: #247BA0; +} +.text-danger{ + color: #E71D36; +} +/* =============Extra Radio and Checkbox Color============= */ diff --git a/public/css/github.min.css b/public/css/github.min.css deleted file mode 100644 index 7b3600c..0000000 --- a/public/css/github.min.css +++ /dev/null @@ -1 +0,0 @@ -.hljs{display:block;overflow-x:auto;padding:.5em;color:#333;background:#f8f8f8}.hljs-comment,.hljs-template_comment,.diff .hljs-header,.hljs-javadoc{color:#998;font-style:italic}.hljs-keyword,.css .rule .hljs-keyword,.hljs-winutils,.javascript .hljs-title,.nginx .hljs-title,.hljs-subst,.hljs-request,.hljs-status{color:#333;font-weight:bold}.hljs-number,.hljs-hexcolor,.ruby .hljs-constant{color:#099}.hljs-string,.hljs-tag .hljs-value,.hljs-phpdoc,.tex .hljs-formula{color:#d14}.hljs-title,.hljs-id,.coffeescript .hljs-params,.scss .hljs-preprocessor{color:#900;font-weight:bold}.javascript .hljs-title,.lisp .hljs-title,.clojure .hljs-title,.hljs-subst{font-weight:normal}.hljs-class .hljs-title,.haskell .hljs-type,.vhdl .hljs-literal,.tex .hljs-command{color:#458;font-weight:bold}.hljs-tag,.hljs-tag .hljs-title,.hljs-rules .hljs-property,.django .hljs-tag .hljs-keyword{color:#000080;font-weight:normal}.hljs-attribute,.hljs-variable,.lisp .hljs-body{color:#008080}.hljs-regexp{color:#009926}.hljs-symbol,.ruby .hljs-symbol .hljs-string,.lisp .hljs-keyword,.tex .hljs-special,.hljs-prompt{color:#990073}.hljs-built_in,.lisp .hljs-title,.clojure .hljs-built_in{color:#0086b3}.hljs-preprocessor,.hljs-pragma,.hljs-pi,.hljs-doctype,.hljs-shebang,.hljs-cdata{color:#999;font-weight:bold}.hljs-deletion{background:#fdd}.hljs-addition{background:#dfd}.diff .hljs-change{background:#0086b3}.hljs-chunk{color:#aaa} \ No newline at end of file diff --git a/public/css/goby.css b/public/css/goby.css index 0f7d50c..bfdca02 100644 --- a/public/css/goby.css +++ b/public/css/goby.css @@ -1,541 +1,1006 @@ +/*================================================================================ +Item Name: Stagb - Sermantic UI Responsive Admin Template +Version: 1.0 +Author: telatkaya_ +Author URL: http://www.themeforest.net/user/telatkaya_ + +[Table of contents] +------------------- +1. Body +2. Clearfix +3. Sidebar,Navbar Change Color List +4. Timeline timeline.html +5. Profile Page profile.html +6. Some Settings (Margins,Paddings e.t.c) +7. Timeline Page Css (Horizontal Timeline) +8. Grid Page grid.html +9. Datatable Page Css datatable.html +10.Mobile Page Settings +11.Typography Settings +================================================================================*/ + +@import "extra_colors.css"; body { - font-family: "Helvetica Neue", "Microsoft YaHei", Arial, Helvetica, sans-serif !important; - background-color: #fff; - overflow-y: scroll; -} -img { - border-radius: 3px; -} -pre, -pre.raw, -pre.wrap, -.dont-break-out { - /* These are technically the same, but use both */ - overflow-wrap: break-word; - word-wrap: break-word; - -ms-word-break: break-all; - /* This is the dangerous one in WebKit, as it breaks things wherever */ - word-break: break-all; - /* Instead use this non-standard one: */ - word-break: break-word; - /* Adds a hyphen where the word breaks, if supported (No Blink) */ - -ms-hyphens: auto; - -moz-hyphens: auto; - -webkit-hyphens: auto; - hyphens: auto; -} -.full.height { - padding: 0; - margin: 0 0 -80px 0; - min-height: 100%; -} -.ui.left { - float: left; -} -.ui.right { - float: right; -} -.ui.container.fluid.padded { - padding: 0 10px 0 10px; -} -.ui.form .ui.button { - font-weight: normal; -} -.ui .text.red { - color: #d95c5c !important; -} -.ui .text.red a { - color: #d95c5c !important; -} -.ui .text.red a:hover { - color: #E67777 !important; -} -.ui .text.blue { - color: #428bca !important; -} -.ui .text.blue a { - color: #15c !important; -} -.ui .text.blue a:hover { - color: #428bca !important; -} -.ui .text.black { - color: #444; -} -.ui .text.black:hover { - color: #000; -} -.ui .text.grey { - color: #767676 !important; -} -.ui .text.grey a { - color: #444 !important; -} -.ui .text.grey a:hover { - color: #000 !important; -} -.ui .text.light.grey { - color: #888 !important; -} -.ui .text.green { - color: #6cc644 !important; -} -.ui .text.purple { - color: #6e5494 !important; -} -.ui .text.yellow { - color: #FBBD08 !important; -} -.ui .text.gold { - color: #a1882b !important; -} -.ui .text.left { - text-align: left !important; -} -.ui .text.right { - text-align: right !important; -} -.ui .text.small { - font-size: 0.75em; -} -.ui .text.normal { - font-weight: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-rendering: geometricPrecision; } -.ui .text.bold { - font-weight: bold; -} -.ui .text.italic { - font-style: italic; -} -.ui .text.truncate { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - display: inline-block; -} -.ui .text.thin { - font-weight: normal; -} -.ui .text.middle { - vertical-align: middle; -} -.ui .message { - text-align: center; -} -.ui .header > i + .content { - padding-left: 0.75rem; - vertical-align: middle; -} -.ui .warning.header { - background-color: #F9EDBE !important; - border-color: #F0C36D; +html, +body { + min-height: 100%; + height: 100%; + background: #f1f4f5; } -.ui .warning.segment { - border-color: #F0C36D; +html.ios { + overflow-x: hidden; + -webkit-overflow-scrolling: touch; } -.ui .info.segment { - border: 1px solid #c5d5dd; +html.ios, +html.ios body { + height: initial !important; } -.ui .info.segment.top { - background-color: #e6f1f6 !important; +.pusher { + min-height: 100%; + height: 100%; + position: relative; } -.ui .info.segment.top h3, -.ui .info.segment.top h4 { - margin-top: 0; +.fullheight { + height: 100%; + min-height: 810px; } -.ui .info.segment.top h3:last-child { - margin-top: 4px; +/* =============Clearfix============= */ + +.no-padding { + padding: 0!important; } -.ui .info.segment.top > :last-child { - margin-bottom: 0; +.clearfix:after { + visibility: hidden; + display: block; + font-size: 0; + content: " "; + clear: both; + height: 0; } -.ui .normal.header { - font-weight: normal; +.clearfix { + display: block; } -.ui .avatar.image { - border-radius: 3px; +* html .clearfix { + height: 1%; } -.ui .form .fake { - display: none !important; +/* =============Clearfix============= */ + +.ui.menu .dropdown.item .menu { + min-width: 180px; } -.ui .form .sub.field { - margin-left: 25px; +.tabmenu { + display: flex !important; + padding: 0 !important; } -.ui .sha.label { - font-family: Consolas, Menlo, Monaco, "Lucida Console", monospace; - font-size: 13px; - padding: 6px 10px 4px 10px; - font-weight: normal; - margin: 0 6px; +.error404 { + background: url(../img/404.png) no-repeat top center #6a8733 !important; + background-size: cover; + width: 100%; + min-height: 100%; + overflow: hidden; } -.ui.status.buttons .octicon { - margin-right: 4px; +/* =============Sidebar,Navbar Change Color List============= */ + +.colorlist, +.sidecolor { + float: left !important; + text-align: left !important; + -webkit-padding-start: 0 !important; + list-style: none; + max-width: 180px; +} +.colorlist li, +.sidecolor li { + float: left; + cursor: pointer; + margin: 1px; +} +.colorlist li a, +.sidecolor li a { + width: 10px; + height: 10px; + display: block; +} +.colorwrap .row .column .segment { + min-height: 268px; +} +.colorwrap .row .column .segment p { + font-size: 1.6em; +} +/* =============Sidebar,Navbar Change Color List============= */ +/* =============Timeline============ */ + +.timeline { + border-left: 1px solid #307473; + margin-left: 15px !important; + position: relative; + padding-bottom: 10px; +} +.timeline:after { + content: ""; + width: 16px; + height: 16px; + border: 2px solid #ccc; + position: absolute; + left: -8.8px; + border-radius: 50%; + background: #307473; + margin-bottom: 10px; +} +.timeline .event { + margin-left: -18px !important; +} +/* =============Timeline============ */ +/* =============Profile Page============ */ + +.profileheader { + background: url(../img/profileheader.jpg) no-repeat top center; + background-size: cover; + width: 100%; + height: 200px; + float: right !important; + text-align: right; + padding: 2em !important; +} +.profilepage .image i { + position: absolute; + right: 0; + top: 0; + margin-right: 10px; + margin-top: 5px; + font-size: 1.1em; +} +/* =============Profile Page============ */ +/* =============Some Settings=========== */ + +.ui.vertical.divider { + left: 50% !important; } -.ui.inline.delete-button { - padding: 8px 15px; - font-weight: normal; +.filtr-item img { + width: 100px; } -.overflow.menu .items { - max-height: 300px; - overflow-y: auto; +.marginlefting { + margin-left: 60px !important; } -.overflow.menu .items .item { - position: relative; - cursor: pointer; - display: block; - border: none; - height: auto; - border-top: none; - line-height: 1em; - color: rgba(0, 0, 0, 0.8); - padding: .71428571em 1.14285714em !important; - font-size: 1rem; - text-transform: none; - font-weight: 400; - box-shadow: none; - -webkit-touch-callout: none; +.displaynone { + display: none !important; } -.overflow.menu .items .item.active { - font-weight: 700; +.displayblock { + display: block !important; } -.overflow.menu .items .item:hover { - background: rgba(0, 0, 0, 0.05); - color: rgba(0, 0, 0, 0.8); - z-index: 13; -} -.scrolling.menu .item.selected { - font-weight: 700 !important; -} -footer { - margin-top: 54px !important; - height: 40px; - background-color: white; - border-top: 1px solid #d6d6d6; - clear: both; - width: 100%; - color: #888888; -} -footer .container { - padding-top: 10px; -} -footer .container .fa { - width: 16px; - text-align: center; - color: #428bca; -} -footer .container .links > * { - border-left: 1px solid #d6d6d6; - padding-left: 8px; - margin-left: 5px; -} -footer .container .links > *:first-child { - border-left: none; -} -footer .ui.language .menu { - max-height: 500px; - overflow-y: auto; - margin-bottom: 7px; -} -.hide { - display: none; -} -.center { - text-align: center; -} -.img-1 { - width: 2px !important; - height: 2px !important; -} -.img-2 { - width: 4px !important; - height: 4px !important; -} -.img-3 { - width: 6px !important; - height: 6px !important; -} -.img-4 { - width: 8px !important; - height: 8px !important; -} -.img-5 { - width: 10px !important; - height: 10px !important; -} -.img-6 { - width: 12px !important; - height: 12px !important; -} -.img-7 { - width: 14px !important; - height: 14px !important; -} -.img-8 { - width: 16px !important; - height: 16px !important; -} -.img-9 { - width: 18px !important; - height: 18px !important; -} -.img-10 { - width: 20px !important; - height: 20px !important; -} -.img-11 { - width: 22px !important; - height: 22px !important; -} -.img-12 { - width: 24px !important; - height: 24px !important; -} -.img-13 { - width: 26px !important; - height: 26px !important; -} -.img-14 { - width: 28px !important; - height: 28px !important; -} -.img-15 { - width: 30px !important; - height: 30px !important; -} -.img-16 { - width: 32px !important; - height: 32px !important; -} -.sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; -} -.sr-only-focusable:active, -.sr-only-focusable:focus { - position: static; - width: auto; - height: auto; - margin: 0; - overflow: visible; - clip: auto; -} -@media only screen and (max-width: 991px) and (min-width: 768px) { - .ui.container { - width: 95%; - } +.sidebar .item i { + font-size: 20px; + margin-top: -5px !important; } +.left.sidebar { + overflow-y: auto !important; +} +.logo { + height: 57px; + background-color: #fff!important; + -webkit-transition-duration: 0.1s; + transition-duration: 0.1s; +} +.logo img { + width: 100% !important; + height: auto; +} +.title.item { + padding: .92857143em 1.14285714em !important; +} +.dropdown .menu .header { + padding-top: 3.9px !important; + padding-bottom: 3.9px !important; +} +.titleIcon { + float: left !important; + margin: 0 10px 0 0 !important; +} +.sidebar::-webkit-scrollbar { + display: none !important; +} +.ui.sidebar.very.thin.icon { + overflow: visible !important; +} +.navslide { + margin-left: 190px; + -webkit-transition-duration: 0.1s; + transition-duration: 0.1s; +} +.mainWrap { + background: #f1f4f5; + min-height: 100%; + position: relative; +} +.mainWrap .segment { + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: 0 1px 1px rgba(0, 0, 0, .05); +} +.pusher .navslide.navwrap .menu { + border-radius: 0; + border: 0; +} +.title .dropdown.icon { + margin-top: 0px !important; +} +.flotchart { + width: 100%; + height: 100px; +} +.flotvisitor { + width: 100%; + height: 300px; +} +.statisticIcon { + position: absolute; + right: 0; + top: 0; + margin-top: 15px !important; + margin-right: 5px !important; + font-size: 4em !important; +} +.column p .wi { + font-size: 1.5em !important; + color: #ff6a00; +} +.ass { + border-radius: 50% !important; +} +.flotTip { + font-size: 12px !important; + background-color: #1f364f !important; + color: #fff; + padding: 5px 8px !important; + z-index: 900 !important; + border-radius: 3px !important; +} +.ui.right.sidebar { + background: #fff; +} +.ui.right.sidebar .tab { + padding: 10px; + min-height: 100% +} +.ui.tabular.menu { + margin-bottom: 0; +} +.ui.button, +.ui.buttons, +.ui.label, +.ui.labels, +.ui.input { + margin-bottom: 10px; +} +/* =============Some Settings=========== */ +/* =============Timeline Page Css (Horizontal Timeline)============= */ -.home { - padding-bottom: 80px; -} -.home .logo { - margin-bottom: 20px; -} -.home .hero h1 { - font-size: 4.5em; -} -.home .hero h2 { - margin-top: 0; - font-size: 2em; -} -.home .hero .octicon { - color: #d9453d; - font-size: 40px; - width: 50px; -} -.home .hero.header { - font-size: 20px; +.cd-horizontal-timeline { + opacity: 0; + margin: 2em auto; + -webkit-transition: opacity 0.2s; + -moz-transition: opacity 0.2s; + transition: opacity 0.2s; +} +.cd-horizontal-timeline ol, +ul { + list-style: none; +} +.cd-horizontal-timeline::before { + /* never visible - this is used in jQuery to check the current MQ */ + + content: 'mobile'; + display: none; +} +.cd-horizontal-timeline.loaded { + /* show the timeline after events position has been set (using JavaScript) */ + + opacity: 1; +} +.cd-horizontal-timeline .h-timeline { + position: relative; + height: 100px; + width: 90%; + max-width: 100%; + margin: 0 auto; +} +.cd-horizontal-timeline .events-wrapper { + position: relative; + height: 100%; + margin: 0 40px; + overflow: hidden; +} +.cd-horizontal-timeline .events-wrapper::after, +.cd-horizontal-timeline .events-wrapper::before { + /* these are used to create a shadow effect at the sides of the timeline */ + + content: ''; + position: absolute; + z-index: 2; + top: 0; + height: 100%; + width: 20px; +} +.cd-horizontal-timeline .events-wrapper::before { + left: 0; + /*background-image: -webkit-linear-gradient( left , #f8f8f8, rgba(248, 248, 248, 0)); + background-image: linear-gradient(to right, #f8f8f8, rgba(248, 248, 248, 0));*/ +} +.cd-horizontal-timeline .events-wrapper::after { + right: 0; + /*background-image: -webkit-linear-gradient( right , #f8f8f8, rgba(248, 248, 248, 0)); + background-image: linear-gradient(to left, #f8f8f8, rgba(248, 248, 248, 0));*/ +} +.cd-horizontal-timeline .events { + /* this is the grey line/timeline */ + + position: absolute; + z-index: 1; + left: 0; + top: 49px; + height: 2px; + /* width will be set using JavaScript */ + + background: #dfdfdf; + -webkit-transition: -webkit-transform 0.4s; + -moz-transition: -moz-transform 0.4s; + transition: transform 0.4s; +} +.cd-horizontal-timeline .filling-line { + /* this is used to create the green line filling the timeline */ + + position: absolute; + z-index: 1; + left: 0; + top: 0; + height: 100%; + width: 100%; + background-color: #7b9d6f; + -webkit-transform: scaleX(0); + -moz-transform: scaleX(0); + -ms-transform: scaleX(0); + -o-transform: scaleX(0); + transform: scaleX(0); + -webkit-transform-origin: left center; + -moz-transform-origin: left center; + -ms-transform-origin: left center; + -o-transform-origin: left center; + transform-origin: left center; + -webkit-transition: -webkit-transform 0.3s; + -moz-transition: -moz-transform 0.3s; + transition: transform 0.3s; +} +.cd-horizontal-timeline .events a { + position: absolute; + bottom: 0; + z-index: 2; + text-align: center; + font-size: 1.3rem; + padding-bottom: 15px; + color: #383838; + /* fix bug on Safari - text flickering while timeline translates */ + + -webkit-transform: translateZ(0); + -moz-transform: translateZ(0); + -ms-transform: translateZ(0); + -o-transform: translateZ(0); + transform: translateZ(0); +} +.cd-horizontal-timeline .events a::after { + /* this is used to create the event spot */ + + content: ''; + position: absolute; + left: 50%; + right: auto; + -webkit-transform: translateX(-50%); + -moz-transform: translateX(-50%); + -ms-transform: translateX(-50%); + -o-transform: translateX(-50%); + transform: translateX(-50%); + bottom: -5px; + height: 12px; + width: 12px; + border-radius: 50%; + border: 2px solid #dfdfdf; + background-color: #f8f8f8; + -webkit-transition: background-color 0.3s, border-color 0.3s; + -moz-transition: background-color 0.3s, border-color 0.3s; + transition: background-color 0.3s, border-color 0.3s; +} +.no-touch .cd-horizontal-timeline .events a:hover::after { + background-color: #7b9d6f; + border-color: #7b9d6f; +} +.cd-horizontal-timeline .events a.selected { + pointer-events: none; +} +.cd-horizontal-timeline .events a.selected::after { + background-color: #7b9d6f; + border-color: #7b9d6f; +} +.cd-horizontal-timeline .events a.older-event::after { + border-color: #7b9d6f; +} +@media only screen and (min-width: 1100px) { + .cd-horizontal-timeline { + margin: 6em auto; + } + .cd-horizontal-timeline::before { + /* never visible - this is used in jQuery to check the current MQ */ + + content: 'desktop'; + } +} +.cd-timeline-navigation a { + /* these are the left/right arrows to navigate the timeline */ + + position: absolute; + z-index: 1; + top: 50%; + bottom: auto; + -webkit-transform: translateY(-50%); + -moz-transform: translateY(-50%); + -ms-transform: translateY(-50%); + -o-transform: translateY(-50%); + transform: translateY(-50%); + height: 34px; + width: 34px; + border-radius: 50%; + border: 2px solid #dfdfdf; + /* replace text with an icon */ + + overflow: hidden; + color: transparent; + text-indent: 100%; + white-space: nowrap; + -webkit-transition: border-color 0.3s; + -moz-transition: border-color 0.3s; + transition: border-color 0.3s; +} +.cd-timeline-navigation a::after { + /* arrow icon */ + + content: ''; + position: absolute; + height: 16px; + width: 16px; + left: 50%; + top: 50%; + bottom: auto; + right: auto; + -webkit-transform: translateX(-50%) translateY(-50%); + -moz-transform: translateX(-50%) translateY(-50%); + -ms-transform: translateX(-50%) translateY(-50%); + -o-transform: translateX(-50%) translateY(-50%); + transform: translateX(-50%) translateY(-50%); + background: url(../img/cd-arrow.svg) no-repeat 0 0; +} +.cd-timeline-navigation a.prev { + left: 0; + -webkit-transform: translateY(-50%) rotate(180deg); + -moz-transform: translateY(-50%) rotate(180deg); + -ms-transform: translateY(-50%) rotate(180deg); + -o-transform: translateY(-50%) rotate(180deg); + transform: translateY(-50%) rotate(180deg); +} +.cd-timeline-navigation a.next { + right: 0; +} +.no-touch .cd-timeline-navigation a:hover { + border-color: #7b9d6f; +} +.cd-timeline-navigation a.inactive { + cursor: not-allowed; +} +.cd-timeline-navigation a.inactive::after { + background-position: 0 -16px; +} +.no-touch .cd-timeline-navigation a.inactive:hover { + border-color: #dfdfdf; +} +.cd-horizontal-timeline .events-content { + position: relative; + width: 100%; + margin: 1em 0 3em 0; + overflow: hidden; + -webkit-transition: height 0.4s; + -moz-transition: height 0.4s; + transition: height 0.4s; + min-height: 150px; +} +.cd-horizontal-timeline .events-content li { + position: absolute; + z-index: 1; + width: 100%; + left: 0; + top: 0; + -webkit-transform: translateX(-100%); + -moz-transform: translateX(-100%); + -ms-transform: translateX(-100%); + -o-transform: translateX(-100%); + transform: translateX(-100%); + padding: 0 5%; + opacity: 0; + -webkit-animation-duration: 0.4s; + -moz-animation-duration: 0.4s; + animation-duration: 0.4s; + -webkit-animation-timing-function: ease-in-out; + -moz-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; +} +.cd-horizontal-timeline .events-content li.selected { + /* visible event content */ + + position: relative; + z-index: 2; + opacity: 1; + -webkit-transform: translateX(0); + -moz-transform: translateX(0); + -ms-transform: translateX(0); + -o-transform: translateX(0); + transform: translateX(0); +} +.cd-horizontal-timeline .events-content li.enter-right, +.cd-horizontal-timeline .events-content li.leave-right { + -webkit-animation-name: cd-enter-right; + -moz-animation-name: cd-enter-right; + animation-name: cd-enter-right; +} +.cd-horizontal-timeline .events-content li.enter-left, +.cd-horizontal-timeline .events-content li.leave-left { + -webkit-animation-name: cd-enter-left; + -moz-animation-name: cd-enter-left; + animation-name: cd-enter-left; +} +.cd-horizontal-timeline .events-content li.leave-right, +.cd-horizontal-timeline .events-content li.leave-left { + -webkit-animation-direction: reverse; + -moz-animation-direction: reverse; + animation-direction: reverse; +} +.cd-horizontal-timeline .events-content li>* { + max-width: 100%; + margin: 0 auto; +} +.cd-horizontal-timeline .events-content h2 { + font-weight: bold; + font-size: 1.6rem; + line-height: 1.2; +} +.cd-horizontal-timeline .events-content em { + display: block; + font-style: italic; + margin: 10px auto; +} +.cd-horizontal-timeline .events-content em::before { + content: '- '; +} +.cd-horizontal-timeline .events-content p { + font-size: 1.4rem; + color: #959595; +} +.cd-horizontal-timeline .events-content em, +.cd-horizontal-timeline .events-content p { + line-height: 1.6; +} +@media only screen and (min-width: 768px) { + .cd-horizontal-timeline .events-content h2 { + font-size: 1rem; + } + .cd-horizontal-timeline .events-content em { + font-size: 1rem; + } + .cd-horizontal-timeline .events-content p { + font-size: 1.1rem; + } +} +@-webkit-keyframes cd-enter-right { + 0% { + opacity: 0; + -webkit-transform: translateX(100%); + } + 100% { + opacity: 1; + -webkit-transform: translateX(0%); + } +} +@-moz-keyframes cd-enter-right { + 0% { + opacity: 0; + -moz-transform: translateX(100%); + } + 100% { + opacity: 1; + -moz-transform: translateX(0%); + } +} +@keyframes cd-enter-right { + 0% { + opacity: 0; + -webkit-transform: translateX(100%); + -moz-transform: translateX(100%); + -ms-transform: translateX(100%); + -o-transform: translateX(100%); + transform: translateX(100%); + } + 100% { + opacity: 1; + -webkit-transform: translateX(0%); + -moz-transform: translateX(0%); + -ms-transform: translateX(0%); + -o-transform: translateX(0%); + transform: translateX(0%); + } +} +@-webkit-keyframes cd-enter-left { + 0% { + opacity: 0; + -webkit-transform: translateX(-100%); + } + 100% { + opacity: 1; + -webkit-transform: translateX(0%); + } +} +@-moz-keyframes cd-enter-left { + 0% { + opacity: 0; + -moz-transform: translateX(-100%); + } + 100% { + opacity: 1; + -moz-transform: translateX(0%); + } +} +@keyframes cd-enter-left { + 0% { + opacity: 0; + -webkit-transform: translateX(-100%); + -moz-transform: translateX(-100%); + -ms-transform: translateX(-100%); + -o-transform: translateX(-100%); + transform: translateX(-100%); + } + 100% { + opacity: 1; + -webkit-transform: translateX(0%); + -moz-transform: translateX(0%); + -ms-transform: translateX(0%); + -o-transform: translateX(0%); + transform: translateX(0%); + } +} +/* =============Timeline Page Css (Horizontal Timeline)============= */ +/* =============Grid Page Css============= */ + +#grid { + font-size: 1.1em; + color: #fff; + text-align: center; + min-height: 30px; + padding: 0 3em; +} +#grid .row .column:nth-child(n) { + background: #48A9A6; + min-height: 30px; + padding: 10px 0; +} +#grid .row .column:nth-child(2n) { + background: #4281A4; + min-height: 30px; + padding: 10px 0; +} +#grid {} #grid h2 { + margin: 2em 0 1.5em; +} +#grid .shaded.examples .row { + position: relative; +} +#grid .shaded.examples .grid>.column { + position: relative; + z-index: 11; +} +#grid .divided.examples .grid .column:not(.row):after { + background-color: #1f364f; + content: ""; + display: block; + min-height: 30px; +} +#grid .nested.examples .grid .grid { + box-shadow: 0 0 0 1px #AAA inset; +} +#grid .simple.examples .grid .column:not(.row):not(.grid):after { + content: ""; + display: block; + min-height: 30px; +} +#grid .shaded.examples .grid .column:not(.row):after, +#grid .nested.examples .grid .grid .column:after { + background-color: #FFF; + box-shadow: 0 0 0 1px #DDD inset; + content: ""; + display: block; + min-height: 30px; +} +/* =============Grid Page Css============= */ +/* =============Datatable Page Css============= */ + +.ui.table.dataTable thead th { + cursor: pointer; + white-space: nowrap; + border-left: 1px solid rgba(34, 36, 38, 0.15); + color: rgba(0, 0, 0, 0.87); +} +.ui.table.dataTable thead th:first-child { + border-left: none; +} +.ui.table.dataTable thead .sorting, +.ui.table.dataTable thead .sorting_asc, +.ui.table.dataTable thead .sorting_desc, +.ui.table.dataTable thead .sorting_asc_disabled, +.ui.table.dataTable thead .sorting_desc_disabled, +.ui.table.dataTable thead .sorting:hover, +.ui.table.dataTable thead .sorting_asc:hover, +.ui.table.dataTable thead .sorting_desc:hover, +.ui.table.dataTable thead .sorting_asc_disabled:hover, +.ui.table.dataTable thead .sorting_desc_disabled:hover { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.ui.table.dataTable thead th:after { + display: none; + font-style: normal; + font-weight: normal; + text-decoration: inherit; + content: ''; + height: 1em; + width: auto; + opacity: 0.8; + margin: 0em 0em 0em 0.5em; + font-family: 'Icons'; +} +.ui.table.dataTable thead th.sorting_asc:after { + /*content: '\f0d8';*/ + + content: '\f160'; +} +.ui.table.dataTable thead th.sorting_desc:after { + /*content: '\f0d7';*/ + + content: '\f161'; +} +.ui.table.dataTable thead th.sorting:after { + content: '\f0dc'; + opacity: 0.2; +} +/* Hover */ + +.ui.table.dataTable th.disabled:hover { + cursor: auto; + color: rgba(40, 40, 40, 0.3); } -.home p.large { - font-size: 16px; +.ui.table.dataTable thead th:hover { + background: rgba(0, 0, 0, 0.05); + color: rgba(0, 0, 0, 0.8); } -.home .stackable { - padding-top: 30px; +/* Sorted */ + +.ui.table.dataTable thead .sorting_asc, +.ui.table.dataTable thead .sorting_desc, +.ui.table.dataTable thead .sorting_asc_disabled, +.ui.table.dataTable thead .sorting_desc_disabled { + background: rgba(0, 0, 0, 0.05); + color: rgba(0, 0, 0, 0.95); +} +.ui.table.dataTable thead .sorting:after, +.ui.table.dataTable thead .sorting_asc:after, +.ui.table.dataTable thead .sorting_desc:after, +.ui.table.dataTable thead .sorting_asc_disabled:after, +.ui.table.dataTable thead .sorting_desc_disabled:after { + display: inline-block; +} +/* Sorted Hover */ + +.ui.table.dataTable thead .sorting_asc:hover, +.ui.table.dataTable thead .sorting_desc:hover, +.ui.table.dataTable thead .sorting_asc_disabled:hover, +.ui.table.dataTable thead .sorting_desc_disabled:hover { + background: rgba(0, 0, 0, 0.05); + color: rgba(0, 0, 0, 0.95); +} +.dataTables_length select { + background: #fff none repeat scroll 0 0; + border: 1px solid rgba(34, 36, 38, 0.15); + border-radius: 0.285714rem; + box-shadow: none; + color: rgba(0, 0, 0, 0.87); + cursor: pointer; + display: inline-block; + line-height: 1.2142em; + min-height: 0.714286em; + outline: 0 none; + padding: 0.3em; + -moz-transform: rotateZ(0deg); + -ms-transform: rotateZ(0deg); + -o-transform: rotateZ(0deg); + -webkit-transform: rotateZ(0deg); + transform: rotateZ(0deg); + -moz-transition: box-shadow 0.1s ease 0s, width 0.1s ease 0s; + -o-transition: box-shadow 0.1s ease 0s, width 0.1s ease 0s; + -webkit-transition: box-shadow 0.1s ease 0s, width 0.1s ease 0s; + transition: box-shadow 0.1s ease 0s, width 0.1s ease 0s; + white-space: normal; + -ms-word-wrap: break-word; + word-wrap: break-word; +} +.dataTables_wrapper .dataTables_filter { + text-align: right; + color: rgba(0, 0, 0, 0.87); + display: inline-flex; + position: relative; +} +.dataTables_wrapper .dataTables_filter input { + margin-left: 0.5em; +} +.dataTables_wrapper .dataTables_info { + clear: both; + padding-top: 0.755em; +} +.dataTables_filter input { + background: #fff none repeat scroll 0 0; + border: 1px solid rgba(34, 36, 38, 0.15); + border-radius: 0.285714rem; + box-shadow: none; + color: rgba(0, 0, 0, 0.87); + -ms-flex: 1 0 auto; + -webkit-flex: 1 0 auto; + flex: 1 0 auto; + height: 1em; + margin: 0; + max-width: 100%; + outline: 0 none; + padding: .4em; + text-align: left; + -moz-transition: background-color 0.1s ease 0s, box-shadow 0.1s ease 0s, border-color 0.1s ease 0s; + -o-transition: background-color 0.1s ease 0s, box-shadow 0.1s ease 0s, border-color 0.1s ease 0s; + -webkit-transition: background-color 0.1s ease 0s, box-shadow 0.1s ease 0s, border-color 0.1s ease 0s; + transition: background-color 0.1s ease 0s, box-shadow 0.1s ease 0s, border-color 0.1s ease 0s; +} +/* =============Datatable Page Css============= */ +/* MOBIL PAGE SETTINGS*/ +/* Desktops and laptops ----------- */ + +@media only screen and (min-width: 1224px) { + .colhidden { + display: block + } + .computer .only { + display: block; + } + #radios { + width: 100%; + } +} +@media only screen and (max-width: 768px) { + /* For mobile phones: */ + + .row .column { + margin-bottom: 20px!important; + } + .ui .buttons { + display: inline!important; + } + .ui .buttons .button { + margin-bottom: 10px; + } + .hiddenui { + display: none!important; + } + .ui.menu .dropdown.item .menu { + height: 100%; + min-height: 15em; + } + .ui .breadcrumb .section { + margin-bottom: 15px; + } + .ui .label { + margin-bottom: 10px!important; + } + .ui.compact.selection.dropdown { + margin-bottom: 10px!important + } + .chat-history { + overflow-y: scroll!important; + } + .icon.link { + margin-bottom: 10px!important + } + .ui.toggle.checkbox, + .ui.slider.checkbox { + margin-bottom: 10px + } + #data_table_filter, + #data_table_info, + #data_table_paginate { + display: none!important + } + #data_table thead tr th { + width: 90%!important; + min-height: 25px!important + } + .colhidden { + display: none!important + } + #radios { + width: 100%; + } +} +/* MOBIL PAGE SETTINGS*/ +/* Typography Styles*/ + +dl { + border: 3px double #ccc; + padding: 0.5em; +} +dt { + float: left; + clear: left; + width: 100px; + text-align: right; + font-weight: bold; + color: #666; +} +dt::after { + content: ":"; +} +dd { + margin: 0px 0 0 110px; + padding: 0 0 0.5em 0; +} +blockquote { + background: #f9f9f9; + border-left: 10px solid #ccc; + margin: 1.5em 10px; + padding: 0.5em 10px; + quotes: "\201C""\201D""\2018""\2019"; +} +blockquote:before { + color: #ccc; + content: open-quote; + font-size: 4em; + line-height: 0.1em; + margin-right: 0.25em; + vertical-align: -0.4em; +} +blockquote p { + display: inline; +} +/* Typography Styles*/ + +.sidemenu { + background: #333c44; } -.home a { - color: #d9453d; +html { + font-size: 12px!important; } -.signup { - padding-top: 15px; - padding-bottom: 80px; +a.item.transition { + margin-left: 30px; } -.install { - padding-top: 45px; - padding-bottom: 80px; +.sidemenu .item { + color: rgba(224, 219, 219, 0.9); } -.install form label { - text-align: right; - width: 320px !important; -} -.install form input { - width: 35% !important; -} -.install form .field { - text-align: left; -} -.install form .field .help { - margin-left: 335px !important; -} -.install form .field.optional .title { - margin-left: 38%; -} -.install .ui .checkbox { - margin-left: 40% !important; -} -.install .ui .checkbox label { - width: auto !important; -} -.install #use-builtin-ssh-server { - margin-top: -1em; - margin-left: -15px !important; - margin-bottom: 2em; -} -.form .help { - color: #999999; - padding-top: .6em; - padding-bottom: .6em; - display: inline-block; - word-break: break-word; -} -.ui.attached.header { - background: #f0f0f0; -} -.ui.attached.header .right { - margin-top: -5px; -} -.ui.attached.header .right .button { - padding: 8px 10px; - font-weight: normal; -} -#create-page-form form { - margin: auto; - width: 800px!important; -} -#create-page-form form .ui.message { - text-align: center; -} -#create-page-form form .header { - padding-left: 280px !important; -} -#create-page-form form .inline.field > label { - text-align: right; - width: 250px !important; - word-wrap: break-word; -} -#create-page-form form .help { - margin-left: 265px !important; -} -#create-page-form form .optional .title { - margin-left: 250px !important; -} -#create-page-form form input, -#create-page-form form textarea { - width: 50%!important; -} -.user.activate form, -.user.forgot.password form, -.user.reset.password form, -.user.signin form, -.user.signup form { - margin: auto; - width: 800px!important; -} -.user.activate form .ui.message, -.user.forgot.password form .ui.message, -.user.reset.password form .ui.message, -.user.signin form .ui.message, -.user.signup form .ui.message { - text-align: center; -} -.user.activate form .header, -.user.forgot.password form .header, -.user.reset.password form .header, -.user.signin form .header, -.user.signup form .header { - padding-left: 280px !important; -} -.user.activate form .inline.field > label, -.user.forgot.password form .inline.field > label, -.user.reset.password form .inline.field > label, -.user.signin form .inline.field > label, -.user.signup form .inline.field > label { - text-align: right; - width: 250px !important; - word-wrap: break-word; -} -.user.activate form .help, -.user.forgot.password form .help, -.user.reset.password form .help, -.user.signin form .help, -.user.signup form .help { - margin-left: 265px !important; -} -.user.activate form .optional .title, -.user.forgot.password form .optional .title, -.user.reset.password form .optional .title, -.user.signin form .optional .title, -.user.signup form .optional .title { - margin-left: 250px !important; -} -.user.activate form input, -.user.forgot.password form input, -.user.reset.password form input, -.user.signin form input, -.user.signup form input, -.user.activate form textarea, -.user.forgot.password form textarea, -.user.reset.password form textarea, -.user.signin form textarea, -.user.signup form textarea { - width: 50%!important; -} -.user.activate form, -.user.forgot.password form, -.user.reset.password form, -.user.signin form, -.user.signup form { - width: 700px!important; -} -.user.activate form .header, -.user.forgot.password form .header, -.user.reset.password form .header, -.user.signin form .header, -.user.signup form .header { - padding-left: 230px !important; -} -.user.activate form .inline.field > label, -.user.forgot.password form .inline.field > label, -.user.reset.password form .inline.field > label, -.user.signin form .inline.field > label, -.user.signup form .inline.field > label { - width: 200px !important; +.ui.left.sidebar, +.ui.right.sidebar { + width: 190px; } -#avatar-arrow:before, -#avatar-arrow:after { - right: 100%; - top: 20px; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; -} -#avatar-arrow:before { - border-right-color: #D4D4D5; - border-width: 9px; - margin-top: -9px; -} -#avatar-arrow:after { - border-right-color: #f7f7f7; - border-width: 8px; - margin-top: -8px; -} +.hiddenCollapse .statistics .label { + opacity: 0.5; +} \ No newline at end of file diff --git a/public/img/add.png b/public/img/add.png new file mode 100644 index 0000000..b5aa5c8 Binary files /dev/null and b/public/img/add.png differ diff --git a/public/img/goby.png b/public/img/goby.png new file mode 100755 index 0000000..19e8b10 Binary files /dev/null and b/public/img/goby.png differ diff --git a/public/img/logo.png b/public/img/logo.png new file mode 100755 index 0000000..643dc5b Binary files /dev/null and b/public/img/logo.png differ diff --git a/public/img/profileheader.jpg b/public/img/profileheader.jpg new file mode 100755 index 0000000..2220391 Binary files /dev/null and b/public/img/profileheader.jpg differ diff --git a/public/img/thumblogo.png b/public/img/thumblogo.png new file mode 100755 index 0000000..a854c8b Binary files /dev/null and b/public/img/thumblogo.png differ diff --git a/public/js/app.js b/public/js/app.js new file mode 100644 index 0000000..be6a97e --- /dev/null +++ b/public/js/app.js @@ -0,0 +1,479 @@ +'use strict' + +$('.ui.form_app_add').form({ + fields: { + name: { + identifier: 'name', + rules: [{ + type: 'empty', + prompt: 'Please enter the app name' + }] + }, + gender: { + identifier: 'platform', + rules: [{ + type: 'empty', + prompt: 'Please select a platform' + }] + } + } +}); + +//collaborator +$("#app_add").on("click", function () { + $("#app_add_modal").modal({ + blurring: true, + transition: 'fade up', + closable: true, + onApprove: function () { + $('.ui.form_app_add').submit(); + return false; + } + }).modal("show"); +}); + +$("#col_add").on("click", function () { + var app_name = $('#app_name').attr('data-name'); + swal({ + title: 'New collaborator', + input: 'email', + text: 'Input an email', + showCancelButton: true, + confirmButtonText: 'Submit', + showLoaderOnConfirm: true, + preConfirm: function (email) { + return new Promise(function (resolve, reject) { + $.ajax({ + url: '/apps/' + app_name + '/collaborators/' + email, + type: 'POST', + success: function (data, textStatus) { + console.log(data); + resolve() + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + reject(XMLHttpRequest.responseJSON.message) + } + }); + }) + }, + allowOutsideClick: false + }).then(function (email) { + swal({ + type: 'success', + title: 'Operation finished!', + html: 'Submitted email: ' + email + }).then(function () { + document.location.reload(); + }); + }).catch(alertError); +}); + + +$(".ui.col_remove").on("click", function () { + + var app_name = $('#app_name').attr('data-name'); + var email = $(this).attr("data-email"); + + swal({ + text: "Are you sure?", + type: 'warning', + showCancelButton: true, + confirmButtonColor: '#3085d6', + cancelButtonColor: '#d33', + confirmButtonText: 'Yes', + preConfirm: function () { + return new Promise(function (resolve, reject) { + $.ajax({ + url: '/apps/' + app_name + '/collaborators/' + email, + type: 'DELETE', + success: function (data, textStatus) { + resolve(email); + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + reject(XMLHttpRequest.responseJSON.message); + } + }); + }) + } + }).then(function (email) { + swal({ + title: 'Removed!', + text: 'Collaborator of ' + email + 'has been removed', + type: 'success' + }).then(function () { + document.location.reload() + }); + }).catch(alertError); +}); + + +$(".ui.col_transfer").on("click", function () { + + var app_name = $('#app_name').attr('data-name'); + var email = $(this).attr("data-email"); + + swal({ + text: "Are you sure to transfer?", + type: 'warning', + showCancelButton: true, + confirmButtonColor: '#3085d6', + cancelButtonColor: '#d33', + confirmButtonText: 'Yes', + preConfirm: function () { + return new Promise(function (resolve, reject) { + $.ajax({ + url: '/apps/' + app_name + '/transfer/' + email, + type: 'POST', + success: function (data, textStatus) { + resolve(email); + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + reject(XMLHttpRequest.responseJSON.message); + } + }); + }) + } + }).then(function (email) { + swal({ + title: 'Transfer!', + text: app_name + ' has been transfer to ' + email, + type: 'success' + }).then(function () { + document.location.href = '/web/app/list'; + }); + }).catch(alertError); +}); + +// deployment +$("#dep_add").on("click", function () { + var app_name = $('#app_name').attr('data-name'); + swal({ + title: 'New deployment', + input: 'text', + text: 'Input a deployment name', + showCancelButton: true, + confirmButtonText: 'Submit', + showLoaderOnConfirm: true, + preConfirm: function (name) { + return new Promise(function (resolve, reject) { + $.ajax({ + url: '/apps/' + app_name + '/deployments', + type: 'POST', + contentType: 'application/json;charset=utf-8', + data: JSON.stringify({ + name: name + }), + success: function (data, textStatus) { + resolve() + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + reject(XMLHttpRequest.responseJSON.message) + } + }); + }) + }, + allowOutsideClick: false + }).then(function (name) { + swal({ + type: 'success', + title: 'Operation finished!', + html: 'Deployment of: ' + name + }).then(function () { + document.location.reload(); + }); + }).catch(alertError); +}); + +$(".ui.dep_delete").on("click", function () { + + var app_name = $('#app_name').attr('data-name'); + var dep_name = $(this).attr("data-name"); + + swal({ + text: "Are you sure?", + type: 'warning', + showCancelButton: true, + confirmButtonColor: '#3085d6', + cancelButtonColor: '#d33', + confirmButtonText: 'Yes', + preConfirm: function () { + return new Promise(function (resolve, reject) { + $.ajax({ + url: '/apps/' + app_name + '/deployments/' + dep_name, + type: 'DELETE', + success: function (data, textStatus) { + resolve(dep_name); + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + reject(XMLHttpRequest.responseJSON.message); + } + }); + }) + } + }).then(function (name) { + swal({ + title: 'Deleted!', + text: 'Deployment of ' + name + 'has been deleted', + type: 'success' + }).then(function () { + document.location.reload() + }); + }).catch(alertError); +}); + +$(".ui.dep_rollback").on("click", function () { + + var app_name = $('#app_name').attr('data-name'); + var dep_name = $(this).attr("data-name"); + + swal({ + text: "Are you sure to rollback the last release", + type: 'warning', + showCancelButton: true, + confirmButtonColor: '#3085d6', + cancelButtonColor: '#d33', + confirmButtonText: 'Yes', + preConfirm: function () { + return new Promise(function (resolve, reject) { + $.ajax({ + url: '/apps/' + app_name + '/deployments/' + dep_name + '/rollback', + type: 'POST', + success: function (data, textStatus) { + resolve(dep_name); + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + reject(XMLHttpRequest.responseJSON.message); + } + }); + }) + } + }).then(function (name) { + swal({ + title: 'Rolled Back', + text: 'The last release of ' + name + 'has been rolled back', + type: 'success' + }).then(function () { + document.location.reload() + }); + }).catch(alertError); +}); + +$(".ui.dep_promote").on("click", function () { + var app_name = $('#app_name').attr('data-name'); + var dep_name = $(this).attr("data-name"); + swal({ + title: 'Promote deployment', + input: 'text', + text: 'Input the dest deployment name', + showCancelButton: true, + confirmButtonText: 'Submit', + showLoaderOnConfirm: true, + preConfirm: function (name) { + return new Promise(function (resolve, reject) { + $.ajax({ + url: '/apps/' + app_name + '/deployments/' + dep_name + '/promote/' + name, + type: 'POST', + success: function (data, textStatus) { + resolve() + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + reject(XMLHttpRequest.responseJSON.message) + } + }); + }) + }, + allowOutsideClick: false + }).then(function (name) { + swal({ + type: 'success', + title: 'Operation finished!', + html: 'Deployment of: ' + name + }).then(function () { + document.location.reload(); + }); + }).catch(alertError); +}); + +$(".ui.dep_new_release").on("click", function () { + var app_name = $('#app_name').attr('data-name'); + var dep_name = $(this).attr("data-name"); + $("#dep_new_release_modal").modal({ + blurring: true, + transition: 'fade up', + closable: false, + onApprove: function () { + $('#release_confirm').addClass('loading'); + var release_form = document.getElementById("form_dep_release"); + var form_data = new FormData(release_form); + + var version = form_data.get('version'); + var rollout = form_data.get('rollout'); + var desc = form_data.get('desc'); + var file = form_data.get('package'); + var packageInfo = { + appVersion: version, + isDisabled: false, + isMandatory: true, + rollout: parseInt(rollout), + description: desc + }; + var up_form = new FormData(); + up_form.append('package', file); + up_form.append('packageInfo', JSON.stringify(packageInfo)); + + $.ajax({ + url: '/apps/' + app_name + '/deployments/' + dep_name + '/release', + type: 'POST', + data: up_form, + processData: false, // 不处理数据 + contentType: false, + success: function (data, textStatus) { + $("#dep_new_release_modal").modal('hide'); + Lobibox.notify('success', { + delay: 2000, + msg: 'success' + }); + var timeOut = setTimeout(function () { + clearTimeout(timeOut); + document.location.reload(); + }, 2100); + + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + $('#release_confirm').removeClass('loading'); + // $("#dep_new_release_modal").modal('hide'); + $('.ui.error.message.release ul').remove(); + $('#form_dep_release').addClass('error'); + $('.ui.error.message.release').append('') + // Lobibox.notify('error', { + // delay: 2000, + // msg:XMLHttpRequest.responseJSON.message + // }); + } + }); + + return false; + } + }).modal("show"); +}); + + + +function fetchHistory(data, callback, settings) { + var app_name = $('#app_name').attr('data-name'); + var dep_name = $('#menu_history').dropdown('get text'); + + var returnData = { + draw: data.draw + }; + + + var pkgs = new Promise(function (resolve, reject) { + $.ajax({ + url: '/apps/' + app_name + '/deployments/' + dep_name + '/history', + type: 'GET', + success: function (data, textStatus) { + resolve(data.history); + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + reject(XMLHttpRequest.responseJSON.message); + } + }); + }); + + var pkgMetrics = new Promise(function (resolve, reject) { + $.ajax({ + url: '/apps/' + app_name + '/deployments/' + dep_name + '/metrics', + type: 'GET', + success: function (data, textStatus) { + resolve(data.metrics); + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + reject(XMLHttpRequest.responseJSON.message); + } + }); + }); + + Promise.all([pkgs, pkgMetrics]).then(function (arr) { + var histories = arr[0]; + var metrics = arr[1]; + var totalActive = getTotalActiveFromDeploymentMetrics(metrics); + histories.forEach(function (packageObject) { + if (metrics[packageObject.label]) { + packageObject.metrics = { + active: metrics[packageObject.label].active, + downloaded: metrics[packageObject.label].downloaded, + failed: metrics[packageObject.label].failed, + installed: metrics[packageObject.label].installed, + totalActive: totalActive + }; + } + }); + return histories; + }).then(function (his) { + returnData.recordsTotal = his.length; + returnData.recordsFiltered = his.length; + returnData.data = his; + if (callback) { + callback(returnData); + } + }).catch(function (err) { + returnData.error = err; + if (callback) { + callback(returnData); + } + }); +} + +function getTotalActiveFromDeploymentMetrics(metrics) { + var totalActive = 0; + Object.keys(metrics).forEach((label) => { + totalActive += metrics[label].active; + }); + + return totalActive; +} + +// $(document).ready(function () { +var table = $('#table_history').dataTable({ + "ordering": false, + "paging": false, + "searching": false, + "initComplete": function () { + // table = this.api(); + // table.draw(); + }, + "ajax": fetchHistory, + "columns": [ + { data: "label" }, + { data: "appVersion" }, + { data: "isMandatory" }, + { data: "releaseMethod" }, + { + data: "uploadTime", + render: function (data, type, row, meta) { + return moment(new Date(data)).format("YYYY-MM-DD hh:mm:ss"); + } + }, + { data: "description" }, + { + data: "metrics", + render: function (data, type, row, meta) { + return '
Active:  ' + (data.totalActive != 0 ? (data.active / data.totalActive * 100).toFixed(1) : 0) + '%(' + data.active + ' of ' + data.totalActive + ')' + '
Total:  ' + data.installed + '
Rollbacks:  ' + data.failed + '
'; + } + } + // ,{ + // data: "label", + // render:function (data, type, row, meta) { + // return ''; + // } + // } + ] +}).api(); + +$('#menu_history').dropdown({ + onChange: function (value, text, $selectedItem) { + table.ajax.reload(); + } +}); +// }); diff --git a/public/js/goby.js b/public/js/goby.js index 645c0ea..e811dbb 100644 --- a/public/js/goby.js +++ b/public/js/goby.js @@ -3,6 +3,17 @@ var csrf; var suburl; +var alertError = function (error) { + if (error === 'cancel') { + return; + } + swal({ + type: 'fail', + title: 'Operation error', + html: error, + showCancelButton: false + }) +}; function initInstall() { if ($('.install').length == 0) { @@ -61,7 +72,7 @@ function initInstall() { }); - $('#disable-registration input').change(function () { + $('#disable-registration input').change(function () { if ($(this).is(':checked')) { $('#enable-captcha').checkbox('uncheck'); } @@ -121,85 +132,181 @@ $(document).ready(function () { csrf = $('meta[name=_csrf]').attr("content"); suburl = $('meta[name=_suburl]').attr("content"); - // Show exact time - $('.time-since').each(function () { - $(this).addClass('poping up').attr('data-content', $(this).attr('title')).attr('data-variation', 'inverted tiny').attr('title', ''); - }); - // Semantic UI modules. - $('.dropdown').dropdown(); - $('.jump.dropdown').dropdown({ - action: 'hide', - onShow: function () { - $('.poping.up').popup('hide'); - } - }); - $('.slide.up.dropdown').dropdown({ - transition: 'slide up' - }); - $('.upward.dropdown').dropdown({ - direction: 'upward' - }); - $('.ui.accordion').accordion(); - $('.ui.checkbox').checkbox(); - $('.ui.progress').progress({ - showActivity: false - }); - $('.poping.up').popup(); - $('.top.menu .poping.up').popup({ - onShow: function () { - if ($('.top.menu .menu.transition').hasClass('visible')) { - return false; - } - } - }); - $('.tabular.menu .item').tab(); - $('.tabable.menu .item').tab(); + buttonsClickOnEnter(); - $('.toggle.button').click(function () { - $($(this).data('target')).slideToggle(100); - }); + initInstall(); +}); + + + +var sideBarIsHide = false; +var ManuelSideBarIsHide = false; +var ManuelSideBarIsState = false; +$(".openbtn").on("click", function () { + ManuelSideBarIsHide = true; + if (!ManuelSideBarIsState) { + resizeSidebar("1"); + ManuelSideBarIsState = true; + } else { + resizeSidebar("0"); + ManuelSideBarIsState = false; + } +}); - // Helpers. - $('.delete-button').click(function () { - var $this = $(this); - $('.delete.modal').modal({ - closable: false, - onApprove: function () { - if ($this.data('type') == "form") { - $($this.data('form')).submit(); - return; - } - - $.post($this.data('url'), { - "_csrf": csrf, - "id": $this.data("id") - }).done(function (data) { - window.location.href = data.redirect; - }); +$(window).resize(function () { + if (ManuelSideBarIsHide == false) { + if ($(window).width() <= 767) { + if (!sideBarIsHide); { + resizeSidebar("1"); + sideBarIsHide = true; + $(".colhidden").addClass("displaynone"); + } - }).modal('show'); - return false; - }); - $('.show-panel.button').click(function () { - $($(this).data('panel')).show(); + } else { + if (sideBarIsHide); { + resizeSidebar("0"); + sideBarIsHide = false; + + $(".colhidden").removeClass("displaynone"); + + } + } + } +}); +var isMobile = window.matchMedia("only screen and (max-width: 768px)"); + +if (isMobile.matches) { + resizeSidebar("1"); + $("body") + .getNiceScroll() + .remove(); + $(".sidebar") + .getNiceScroll() + .remove(); + + $(".computer.only").toggleClass("displaynone"); + $(".colhidden").toggleClass("displaynone"); +} else { + $("body").niceScroll({ + cursorcolor: "#3d3b3b", + cursorwidth: 5, + cursorborderradius: 0, + cursorborder: 0, + scrollspeed: 50, + autohidemode: true, + zindex: 9999999 }); - $('.show-modal.button').click(function () { - $($(this).data('modal')).modal('show'); + $(".sidebar").niceScroll({ + cursorcolor: "#3d3b3b", + cursorwidth: 2, + cursorborderradius: 0, + cursorborder: 0, + scrollspeed: 50, + autohidemode: true, + zindex: 9999999 }); - $('.delete-post.button').click(function () { - var $this = $(this); - $.post($this.data('request-url'), { - "_csrf": csrf - }).done(function () { - window.location.href = $this.data('done-url'); - }); + + $(".displaynone .menu").niceScroll({ + cursorcolor: "#3d3b3b", + cursorwidth: 5, + cursorborderradius: 0, + cursorborder: 0, + scrollspeed: 50, + autohidemode: true, + zindex: 9999999 }); +} +function resizeSidebar(op) { - buttonsClickOnEnter(); + if (op == "1") { - initInstall(); + $(".ui.sidebar.left").addClass("very thin icon"); + $(".navslide").addClass("marginlefting"); + $(".sidebar.left span").addClass("displaynone"); + $(".sidebar .accordion").addClass("displaynone"); + $(".ui.dropdown.item.displaynone").addClass("displayblock"); + $($(".logo img")[0]).addClass("displaynone"); + $($(".logo img")[1]).removeClass("displaynone"); + $(".hiddenCollapse").addClass("displaynone"); + + + } else { + + $(".ui.sidebar.left").removeClass("very thin icon"); + $(".navslide").removeClass("marginlefting"); + $(".sidebar.left span").removeClass("displaynone"); + $(".sidebar .accordion").removeClass("displaynone"); + $(".ui.dropdown.item.displaynone").removeClass("displayblock"); + $($(".logo img")[1]).addClass("displaynone"); + $($(".logo img")[0]).removeClass("displaynone"); + $(".hiddenCollapse").removeClass("displaynone"); + + + } + +} + +$(".ui.dropdown").dropdown({ + allowCategorySelection: true, + transition: "fade up" +}); +$('.ui.accordion').accordion({ + selector: {} }); + +//Sidebar And Navbar Coloring Function (This button on Footer) +function colorize() { + var a; + var b; + var d; + var z; + var l; + + if (Cookies.get('sidebarColor') != undefined) { + if (b == null) { + b = $(".sidebar").attr("data-color"); + } + $(".sidemenu").removeClass(b).addClass(Cookies.get('sidebarColor')); + $(".sidebar").attr("data-color", Cookies.get('sidebarColor')); + } + + if (Cookies.get('headerColor') != undefined) { + if (z == null) { + z = $(".navslide .menu").attr("data-color"); + } + $(".navslide .menu").removeClass(z).addClass(Cookies.get('headerColor')); + $(".navslide .menu").attr("data-color", Cookies.get('headerColor')); + } + + + + $(".colorlist li a").on("click", function (b) { + var c = $(this).attr("data-addClass"); + if (l == null) { + l = $(".navslide .menu").attr("data-color"); + } + console.log(l); + $(".navslide .menu").removeClass(l).addClass(c); + l = c; + Cookies.set('headerColor', c); + }); + $(".sidecolor li a").on("click", function (a) { + var c = $(this).attr("data-addClass"); + // a.preventDefault(); + if (d == null) { + d = $(".sidebar").attr("data-color"); + } + $(".sidemenu").removeClass(d).addClass(c); + $(".accordion").removeClass("inverted").addClass("inverted"); + Cookies.set('sidebarColor', c); + d = c; + }); + $(".colorize").popup({ + on: "click" + }); +} (function (i, s, o, g, r, a, m) { i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () { (i[r].q = i[r].q || []).push(arguments) }, i[r].l = 1 * new Date(); a = s.createElement(o), m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m) })(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga'); ga('create', 'UA-96662612-1', 'auto'); ga('send', 'pageview'); +//Sidebar And Navbar Coloring Function (This button on Footer) \ No newline at end of file diff --git a/public/js/key.js b/public/js/key.js new file mode 100644 index 0000000..35aea7c --- /dev/null +++ b/public/js/key.js @@ -0,0 +1,96 @@ + +$('#key_add').on("click", function () { + var creator = $(this).attr('data-creator'); + $("#key_add_modal").modal({ + blurring: true, + transition: 'fade up', + closable: true, + onApprove: function () { + var key_form = document.getElementById("form_key_add"); + var form_data = new FormData(key_form); + + var name = form_data.get('name'); + var date = form_data.get('expire_date'); + + var d = new Date(date); + var td = new Date(); + var ttl = d.getTime() - td.getTime(); + + var up_form = new FormData(); + up_form.append('friendlyName', name); + up_form.append('createdBy', creator); + up_form.append('description', ''); + up_form.append('ttl', ttl); + + $('#key_confirm').addClass('loading'); + $.ajax({ + url: '/accessKeys', + type: 'POST', + data: up_form, + processData: false, // 不处理数据 + contentType: false, + success: function (data, textStatus) { + + $("#key_add_modal").modal('hide'); + Lobibox.notify('success', { + delay: 2000, + msg: 'success' + }); + var timeOut = setTimeout(function () { + clearTimeout(timeOut); + document.location.reload(); + }, 2100); + + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + $('#key_confirm').removeClass('loading'); + $('#form_key_error ul').remove(); + $('#form_key_add').addClass('error'); + $('#form_key_error').append('') + } + }); + + return false; + } + }).modal("show"); + $('#key_calendar').calendar({ + ampm: false, + type: 'date' + }); +}); + + +$(".ui.key_delete").on("click", function () { + + var key_name = $(this).attr('data-name'); + swal({ + text: "Are you sure to delete this key?", + type: 'warning', + showCancelButton: true, + confirmButtonColor: '#3085d6', + cancelButtonColor: '#d33', + confirmButtonText: 'Yes', + preConfirm: function () { + return new Promise(function (resolve, reject) { + $.ajax({ + url: '/accessKeys/' + key_name, + type: 'DELETE', + success: function (data, textStatus) { + resolve(key_name); + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + reject(XMLHttpRequest.responseJSON.message); + } + }); + }) + } + }).then(function (key_name) { + swal({ + title: 'Deleted!', + text: 'Key of ' + key_name + 'has been deleted', + type: 'success' + }).then(function () { + document.location.reload() + }); + }).catch(alertError); +}); \ No newline at end of file diff --git a/public/plugins/calendar/calendar.min.css b/public/plugins/calendar/calendar.min.css new file mode 100755 index 0000000..b0fe9b5 --- /dev/null +++ b/public/plugins/calendar/calendar.min.css @@ -0,0 +1,9 @@ +/*! + * # Semantic UI 0.0.8 - Calendar + * http://github.com/semantic-org/semantic-ui/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */.ui.calendar .ui.popup{max-width:none;padding:0;border:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ui.calendar .calendar:focus{outline:0}.ui.calendar .ui.popup .ui.grid{display:block;white-space:nowrap}.ui.calendar .ui.popup .ui.grid>.column{width:auto}.ui.calendar .ui.table.minute,.ui.calendar .ui.table.month,.ui.calendar .ui.table.year{min-width:15em}.ui.calendar .ui.table.day{min-width:18em}.ui.calendar .ui.table.hour{min-width:20em}.ui.calendar .ui.table tr td,.ui.calendar .ui.table tr th{padding:.5em;white-space:nowrap}.ui.calendar .ui.table tr th{border-left:none}.ui.calendar .ui.table tr th .icon{margin:0}.ui.calendar .ui.table tr:first-child th{position:relative;padding-left:0;padding-right:0}.ui.calendar .ui.table.day tr:first-child th{border:none}.ui.calendar .ui.table.day tr:nth-child(2) th{padding-top:.2em;padding-bottom:.3em}.ui.calendar .ui.table tr td{padding-left:.1em;padding-right:.1em}.ui.calendar .ui.table tr .link{cursor:pointer}.ui.calendar .ui.table tr .prev.link{width:14.28571429%;position:absolute;left:0}.ui.calendar .ui.table tr .next.link{width:14.28571429%;position:absolute;right:0}.ui.calendar .ui.table tr .disabled{pointer-events:none;color:rgba(40,40,40,.3)}.ui.calendar .ui.table tr td.today{font-weight:700}.ui.calendar .ui.table tr td.range{background:rgba(0,0,0,.05);color:rgba(0,0,0,.95);box-shadow:none}.ui.calendar .ui.table.inverted tr td.range{background:rgba(255,255,255,.08);color:#fff;box-shadow:none}.ui.calendar .calendar.active .ui.table tbody tr td.focus,.ui.calendar .calendar.active .ui.table.inverted tbody tr td.focus,.ui.calendar .calendar:focus .ui.table tbody tr td.focus,.ui.calendar .calendar:focus .ui.table.inverted tbody tr td.focus{box-shadow:inset 0 0 0 1px #85B7D9} \ No newline at end of file diff --git a/public/plugins/calendar/calendar.min.js b/public/plugins/calendar/calendar.min.js new file mode 100755 index 0000000..7cda4b8 --- /dev/null +++ b/public/plugins/calendar/calendar.min.js @@ -0,0 +1 @@ +!function(e,t,a,n){"use strict";t="undefined"!=typeof t&&t.Math==Math?t:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")(),e.fn.calendar=function(t){var o,r=e(this),i=r.selector||"",l=(new Date).getTime(),d=[],s=arguments[0],u="string"==typeof s,p=[].slice.call(arguments,1);return r.each(function(){var r,c,f=e.isPlainObject(t)?e.extend(!0,{},e.fn.calendar.settings,t):e.extend({},e.fn.calendar.settings),h=f.className,g=f.namespace,m=f.selector,v=f.formatter,y=f.parser,D=f.metadata,b=f.error,C="."+g,M="module-"+g,w=e(this),x=w.find(m.input),k=w.find(m.popup),T=w.find(m.activator),F=this,H=w.data(M),O=!1,I=!1;c={initialize:function(){c.debug("Initializing calendar for",F),r=c.get.isTouch(),c.setup.popup(),c.setup.inline(),c.setup.input(),c.setup.date(),c.create.calendar(),c.bind.events(),c.instantiate()},instantiate:function(){c.verbose("Storing instance of calendar"),H=c,w.data(M,H)},destroy:function(){c.verbose("Destroying previous calendar for",F),w.removeData(M),c.unbind.events()},setup:{popup:function(){if(!f.inline&&(T.length||(T=w.children().first(),T.length))){if(e.fn.popup===n)return void c.error(b.popup);k.length||(k=e("
").addClass(h.popup).prependTo(T.parent())),k.addClass(h.calendar);var t=f.onVisible,a=f.onHidden;x.length||(k.attr("tabindex","0"),t=function(){return c.focus(),f.onVisible.apply(k,arguments)},a=function(){return c.blur(),f.onHidden.apply(k,arguments)});var o=function(){return c.set.focusDate(c.get.date()),c.set.mode(f.startMode),f.onShow.apply(k,arguments)},r=f.on||(x.length?"focus":"click"),i=e.extend({},f.popupOptions,{popup:k,on:r,hoverable:"hover"===r,onShow:o,onVisible:t,onHide:f.onHide,onHidden:a});c.popup(i)}},inline:function(){T.length&&!f.inline||(k=e("
").addClass(h.calendar).appendTo(w),x.length||k.attr("tabindex","0"))},input:function(){f.touchReadonly&&x.length&&r&&x.prop("readonly",!0)},date:function(){if(x.length){var e=x.val(),t=y.date(e,f);c.set.date(t,f.formatInput,!1)}}},create:{calendar:function(){var t,a,n,o,r,i,l,d=c.get.mode(),s=new Date,u=c.get.date(),p=c.get.focusDate(),g=p||u||f.initialDate||s;g=c.helper.dateInRange(g),p||(p=g,c.set.focusDate(p,!1,!1));var m="year"===d,y="month"===d,b="day"===d,C="hour"===d,M="minute"===d,w="time"===f.type,x=Math.max(f.multiMonth,1),T=b?c.get.monthOffset():0,F=g.getMinutes(),H=g.getHours(),O=g.getDate(),I=g.getMonth()+T,N=g.getFullYear(),Y=b?7:C?4:3,E=7===Y?"seven":4===Y?"four":"three",R=b||C?6:4,j=b?x:1,A=k;for(A.empty(),j>1&&(l=e("
").addClass(h.grid).appendTo(A)),o=0;o1){var S=e("
").addClass(h.column).appendTo(l);A=S}var V=I+o,P=(new Date(N,V,1).getDay()-f.firstDayOfWeek%7+7)%7;if(!f.constantHeight&&b){var q=new Date(N,V+1,0).getDate()+P;R=Math.ceil(q/7)}var K=m?10:y?1:0,J=b?1:0,W=C||M?1:0,z=C||M?O:1,L=new Date(N-K,V-J,z-W,H),B=new Date(N+K,V+J,z+W,H),U=m?new Date(10*Math.ceil(N/10)-9,0,0):y?new Date(N,0,0):b?new Date(N,V,0):new Date(N,V,O,(-1)),Q=m?new Date(10*Math.ceil(N/10)+1,0,1):y?new Date(N+1,0,1):b?new Date(N,V+1,1):new Date(N,V,O+1),Z=e("").addClass(h.table).addClass(E+" column").addClass(d).appendTo(A);if(!w){var G=e("").appendTo(Z);r=e("").appendTo(G),i=e("").appendTo(G),t=0;t").appendTo(r),i.text(v.dayColumnHeader((t+f.firstDayOfWeek)%7,f))}var ae=e("").appendTo(Z);for(t=m?10*Math.ceil(N/10)-9:b?1-P:0,a=0;a").appendTo(ae),n=0;n").addClass(h.cell).appendTo(r),i.text(oe),i.data(D.date,ne);var re=b&&ne.getMonth()!==(V+12)%12,ie=re||!c.helper.isDateInRange(ne,d)||f.isDisabled(ne,d),le=c.helper.dateEqual(ne,u,d),de=c.helper.dateEqual(ne,s,d);i.toggleClass(h.adjacentCell,re),i.toggleClass(h.disabledCell,ie),i.toggleClass(h.activeCell,le&&!re),C||M||i.toggleClass(h.todayCell,!re&&de);var se={mode:d,adjacent:re,disabled:ie,active:le,today:de};v.cell(i,ne,se),c.helper.dateEqual(ne,p,d)&&c.set.focusDate(ne,!1,!1)}if(f.today){var ue=e("").appendTo(ae),pe=e("').appendTo(this); + } + oSettings.nTBody = tbody[0]; + + var tfoot = $this.children('tfoot'); + if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") ) + { + // If we are a scrolling table, and no footer has been given, then we need to create + // a tfoot element for the caption element to be appended to + tfoot = $('').appendTo(this); + } + + if ( tfoot.length === 0 || tfoot.children().length === 0 ) { + $this.addClass( oClasses.sNoFooter ); + } + else if ( tfoot.length > 0 ) { + oSettings.nTFoot = tfoot[0]; + _fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot ); + } + + /* Check if there is data passing into the constructor */ + if ( oInit.aaData ) + { + for ( i=0 ; i idx ? + new _Api( ctx[idx], this[idx] ) : + null; + }, + + + filter: function ( fn ) + { + var a = []; + + if ( __arrayProto.filter ) { + a = __arrayProto.filter.call( this, fn, this ); + } + else { + // Compatibility for browsers without EMCA-252-5 (JS 1.6) + for ( var i=0, ien=this.length ; i 0 ) { + return ctx[0].json; + } + + // else return undefined; + } ); + + + /** + * Get the data submitted in the last Ajax request + */ + _api_register( 'ajax.params()', function () { + var ctx = this.context; + + if ( ctx.length > 0 ) { + return ctx[0].oAjaxData; + } + + // else return undefined; + } ); + + + /** + * Reload tables from the Ajax data source. Note that this function will + * automatically re-draw the table when the remote data has been loaded. + * + * @param {boolean} [reset=true] Reset (default) or hold the current paging + * position. A full re-sort and re-filter is performed when this method is + * called, which is why the pagination reset is the default action. + * @returns {DataTables.Api} this + */ + _api_register( 'ajax.reload()', function ( callback, resetPaging ) { + return this.iterator( 'table', function (settings) { + __reload( settings, resetPaging===false, callback ); + } ); + } ); + + + /** + * Get the current Ajax URL. Note that this returns the URL from the first + * table in the current context. + * + * @return {string} Current Ajax source URL + *//** + * Set the Ajax URL. Note that this will set the URL for all tables in the + * current context. + * + * @param {string} url URL to set. + * @returns {DataTables.Api} this + */ + _api_register( 'ajax.url()', function ( url ) { + var ctx = this.context; + + if ( url === undefined ) { + // get + if ( ctx.length === 0 ) { + return undefined; + } + ctx = ctx[0]; + + return ctx.ajax ? + $.isPlainObject( ctx.ajax ) ? + ctx.ajax.url : + ctx.ajax : + ctx.sAjaxSource; + } + + // set + return this.iterator( 'table', function ( settings ) { + if ( $.isPlainObject( settings.ajax ) ) { + settings.ajax.url = url; + } + else { + settings.ajax = url; + } + // No need to consider sAjaxSource here since DataTables gives priority + // to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any + // value of `sAjaxSource` redundant. + } ); + } ); + + + /** + * Load data from the newly set Ajax URL. Note that this method is only + * available when `ajax.url()` is used to set a URL. Additionally, this method + * has the same effect as calling `ajax.reload()` but is provided for + * convenience when setting a new URL. Like `ajax.reload()` it will + * automatically redraw the table once the remote data has been loaded. + * + * @returns {DataTables.Api} this + */ + _api_register( 'ajax.url().load()', function ( callback, resetPaging ) { + // Same as a reload, but makes sense to present it for easy access after a + // url change + return this.iterator( 'table', function ( ctx ) { + __reload( ctx, resetPaging===false, callback ); + } ); + } ); + + + + + var _selector_run = function ( type, selector, selectFn, settings, opts ) + { + var + out = [], res, + a, i, ien, j, jen, + selectorType = typeof selector; + + // Can't just check for isArray here, as an API or jQuery instance might be + // given with their array like look + if ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) { + selector = [ selector ]; + } + + for ( i=0, ien=selector.length ; i 0 ) { + // Assign the first element to the first item in the instance + // and truncate the instance and context + inst[0] = inst[i]; + inst[0].length = 1; + inst.length = 1; + inst.context = [ inst.context[i] ]; + + return inst; + } + } + + // Not found - return an empty instance + inst.length = 0; + return inst; + }; + + + var _selector_row_indexes = function ( settings, opts ) + { + var + i, ien, tmp, a=[], + displayFiltered = settings.aiDisplay, + displayMaster = settings.aiDisplayMaster; + + var + search = opts.search, // none, applied, removed + order = opts.order, // applied, current, index (original - compatibility with 1.9) + page = opts.page; // all, current + + if ( _fnDataSource( settings ) == 'ssp' ) { + // In server-side processing mode, most options are irrelevant since + // rows not shown don't exist and the index order is the applied order + // Removed is a special case - for consistency just return an empty + // array + return search === 'removed' ? + [] : + _range( 0, displayMaster.length ); + } + else if ( page == 'current' ) { + // Current page implies that order=current and fitler=applied, since it is + // fairly senseless otherwise, regardless of what order and search actually + // are + for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i= 0 && search == 'applied') ) + { + a.push( i ); + } + } + } + } + + return a; + }; + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Rows + * + * {} - no selector - use all available rows + * {integer} - row aoData index + * {node} - TR node + * {string} - jQuery selector to apply to the TR elements + * {array} - jQuery array of nodes, or simply an array of TR nodes + * + */ + + + var __row_selector = function ( settings, selector, opts ) + { + var run = function ( sel ) { + var selInt = _intVal( sel ); + var i, ien; + + // Short cut - selector is a number and no options provided (default is + // all records, so no need to check if the index is in there, since it + // must be - dev error if the index doesn't exist). + if ( selInt !== null && ! opts ) { + return [ selInt ]; + } + + var rows = _selector_row_indexes( settings, opts ); + + if ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) { + // Selector - integer + return [ selInt ]; + } + else if ( ! sel ) { + // Selector - none + return rows; + } + + // Selector - function + if ( typeof sel === 'function' ) { + return $.map( rows, function (idx) { + var row = settings.aoData[ idx ]; + return sel( idx, row._aData, row.nTr ) ? idx : null; + } ); + } + + // Get nodes in the order from the `rows` array with null values removed + var nodes = _removeEmpty( + _pluck_order( settings.aoData, rows, 'nTr' ) + ); + + // Selector - node + if ( sel.nodeName ) { + if ( sel._DT_RowIndex !== undefined ) { + return [ sel._DT_RowIndex ]; // Property added by DT for fast lookup + } + else if ( sel._DT_CellIndex ) { + return [ sel._DT_CellIndex.row ]; + } + else { + var host = $(sel).closest('*[data-dt-row]'); + return host.length ? + [ host.data('dt-row') ] : + []; + } + } + + // ID selector. Want to always be able to select rows by id, regardless + // of if the tr element has been created or not, so can't rely upon + // jQuery here - hence a custom implementation. This does not match + // Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything, + // but to select it using a CSS selector engine (like Sizzle or + // querySelect) it would need to need to be escaped for some characters. + // DataTables simplifies this for row selectors since you can select + // only a row. A # indicates an id any anything that follows is the id - + // unescaped. + if ( typeof sel === 'string' && sel.charAt(0) === '#' ) { + // get row index from id + var rowObj = settings.aIds[ sel.replace( /^#/, '' ) ]; + if ( rowObj !== undefined ) { + return [ rowObj.idx ]; + } + + // need to fall through to jQuery in case there is DOM id that + // matches + } + + // Selector - jQuery selector string, array of nodes or jQuery object/ + // As jQuery's .filter() allows jQuery objects to be passed in filter, + // it also allows arrays, so this will cope with all three options + return $(nodes) + .filter( sel ) + .map( function () { + return this._DT_RowIndex; + } ) + .toArray(); + }; + + return _selector_run( 'row', selector, run, settings, opts ); + }; + + + _api_register( 'rows()', function ( selector, opts ) { + // argument shifting + if ( selector === undefined ) { + selector = ''; + } + else if ( $.isPlainObject( selector ) ) { + opts = selector; + selector = ''; + } + + opts = _selector_opts( opts ); + + var inst = this.iterator( 'table', function ( settings ) { + return __row_selector( settings, selector, opts ); + }, 1 ); + + // Want argument shifting here and in __row_selector? + inst.selector.rows = selector; + inst.selector.opts = opts; + + return inst; + } ); + + _api_register( 'rows().nodes()', function () { + return this.iterator( 'row', function ( settings, row ) { + return settings.aoData[ row ].nTr || undefined; + }, 1 ); + } ); + + _api_register( 'rows().data()', function () { + return this.iterator( true, 'rows', function ( settings, rows ) { + return _pluck_order( settings.aoData, rows, '_aData' ); + }, 1 ); + } ); + + _api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) { + return this.iterator( 'row', function ( settings, row ) { + var r = settings.aoData[ row ]; + return type === 'search' ? r._aFilterData : r._aSortData; + }, 1 ); + } ); + + _api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) { + return this.iterator( 'row', function ( settings, row ) { + _fnInvalidate( settings, row, src ); + } ); + } ); + + _api_registerPlural( 'rows().indexes()', 'row().index()', function () { + return this.iterator( 'row', function ( settings, row ) { + return row; + }, 1 ); + } ); + + _api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) { + var a = []; + var context = this.context; + + // `iterator` will drop undefined values, but in this case we want them + for ( var i=0, ien=context.length ; i').addClass( k ); + $('td', created) + .addClass( k ) + .html( r ) + [0].colSpan = _fnVisbleColumns( ctx ); + + rows.push( created[0] ); + } + }; + + addRow( data, klass ); + + if ( row._details ) { + row._details.remove(); + } + + row._details = $(rows); + + // If the children were already shown, that state should be retained + if ( row._detailsShow ) { + row._details.insertAfter( row.nTr ); + } + }; + + + var __details_remove = function ( api, idx ) + { + var ctx = api.context; + + if ( ctx.length ) { + var row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ]; + + if ( row && row._details ) { + row._details.remove(); + + row._detailsShow = undefined; + row._details = undefined; + } + } + }; + + + var __details_display = function ( api, show ) { + var ctx = api.context; + + if ( ctx.length && api.length ) { + var row = ctx[0].aoData[ api[0] ]; + + if ( row._details ) { + row._detailsShow = show; + + if ( show ) { + row._details.insertAfter( row.nTr ); + } + else { + row._details.detach(); + } + + __details_events( ctx[0] ); + } + } + }; + + + var __details_events = function ( settings ) + { + var api = new _Api( settings ); + var namespace = '.dt.DT_details'; + var drawEvent = 'draw'+namespace; + var colvisEvent = 'column-visibility'+namespace; + var destroyEvent = 'destroy'+namespace; + var data = settings.aoData; + + api.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent ); + + if ( _pluck( data, '_details' ).length > 0 ) { + // On each draw, insert the required elements into the document + api.on( drawEvent, function ( e, ctx ) { + if ( settings !== ctx ) { + return; + } + + api.rows( {page:'current'} ).eq(0).each( function (idx) { + // Internal data grab + var row = data[ idx ]; + + if ( row._detailsShow ) { + row._details.insertAfter( row.nTr ); + } + } ); + } ); + + // Column visibility change - update the colspan + api.on( colvisEvent, function ( e, ctx, idx, vis ) { + if ( settings !== ctx ) { + return; + } + + // Update the colspan for the details rows (note, only if it already has + // a colspan) + var row, visible = _fnVisbleColumns( ctx ); + + for ( var i=0, ien=data.length ; i=0 count from left, <0 count from right) + * "{integer}:visIdx" - visible column index (i.e. translate to column index) (>=0 count from left, <0 count from right) + * "{integer}:visible" - alias for {integer}:visIdx (>=0 count from left, <0 count from right) + * "{string}:name" - column name + * "{string}" - jQuery selector on column header nodes + * + */ + + // can be an array of these items, comma separated list, or an array of comma + // separated lists + + var __re_column_selector = /^(.+):(name|visIdx|visible)$/; + + + // r1 and r2 are redundant - but it means that the parameters match for the + // iterator callback in columns().data() + var __columnData = function ( settings, column, r1, r2, rows ) { + var a = []; + for ( var row=0, ien=rows.length ; row= 0 ? + selInt : // Count from left + columns.length + selInt // Count from right (+ because its a negative value) + ]; + } + + // Selector = function + if ( typeof s === 'function' ) { + var rows = _selector_row_indexes( settings, opts ); + + return $.map( columns, function (col, idx) { + return s( + idx, + __columnData( settings, idx, 0, 0, rows ), + nodes[ idx ] + ) ? idx : null; + } ); + } + + // jQuery or string selector + var match = typeof s === 'string' ? + s.match( __re_column_selector ) : + ''; + + if ( match ) { + switch( match[2] ) { + case 'visIdx': + case 'visible': + var idx = parseInt( match[1], 10 ); + // Visible index given, convert to column index + if ( idx < 0 ) { + // Counting from the right + var visColumns = $.map( columns, function (col,i) { + return col.bVisible ? i : null; + } ); + return [ visColumns[ visColumns.length + idx ] ]; + } + // Counting from the left + return [ _fnVisibleToColumnIndex( settings, idx ) ]; + + case 'name': + // match by name. `names` is column index complete and in order + return $.map( names, function (name, i) { + return name === match[1] ? i : null; + } ); + + default: + return []; + } + } + + // Cell in the table body + if ( s.nodeName && s._DT_CellIndex ) { + return [ s._DT_CellIndex.column ]; + } + + // jQuery selector on the TH elements for the columns + var jqResult = $( nodes ) + .filter( s ) + .map( function () { + return $.inArray( this, nodes ); // `nodes` is column index complete and in order + } ) + .toArray(); + + if ( jqResult.length || ! s.nodeName ) { + return jqResult; + } + + // Otherwise a node which might have a `dt-column` data attribute, or be + // a child or such an element + var host = $(s).closest('*[data-dt-column]'); + return host.length ? + [ host.data('dt-column') ] : + []; + }; + + return _selector_run( 'column', selector, run, settings, opts ); + }; + + + var __setColumnVis = function ( settings, column, vis, recalc ) { + var + cols = settings.aoColumns, + col = cols[ column ], + data = settings.aoData, + row, cells, i, ien, tr; + + // Get + if ( vis === undefined ) { + return col.bVisible; + } + + // Set + // No change + if ( col.bVisible === vis ) { + return; + } + + if ( vis ) { + // Insert column + // Need to decide if we should use appendChild or insertBefore + var insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 ); + + for ( i=0, ien=data.length ; i iThat; + } + + return true; + }; + + + /** + * Check if a `
").attr("colspan",""+Y).appendTo(r);var X=m||y?new Date(N,0,1):b?new Date(N,V,1):new Date(N,V,O,H,F),$=e("").addClass(h.link).appendTo(i);$.text(v.header(X,d,f));var _=y?f.disableYear?"day":"year":b?f.disableMonth?"year":"month":"day";if($.data(D.mode,_),0===o){var ee=e("").addClass(h.prev).appendTo(i);ee.data(D.focusDate,L),ee.toggleClass(h.disabledCell,!c.helper.isDateInRange(U,d)),e("").addClass(h.prevIcon).appendTo(ee)}if(o===j-1){var te=e("").addClass(h.next).appendTo(i);te.data(D.focusDate,B),te.toggleClass(h.disabledCell,!c.helper.isDateInRange(Q,d)),e("").addClass(h.nextIcon).appendTo(te)}if(b)for(r=e("
").attr("colspan",""+Y).addClass(h.today).appendTo(ue);pe.text(v.today(f)),pe.data(D.date,s)}c.update.focus(!1,Z)}}},update:{focus:function(t,a){a=a||k;var n=c.get.mode(),o=c.get.date(),i=c.get.focusDate(),l=c.get.startDate(),d=c.get.endDate(),s=(t?i:null)||o||(r?null:i);a.find("td").each(function(){var t=e(this),a=t.data(D.date);if(a){var o=t.hasClass(h.disabledCell),u=t.hasClass(h.activeCell),p=t.hasClass(h.adjacentCell),f=c.helper.dateEqual(a,i,n),g=!!s&&(!!l&&c.helper.isDateInRange(a,n,l,s)||!!d&&c.helper.isDateInRange(a,n,s,d));t.toggleClass(h.focusCell,f&&(!r||O)&&!p),t.toggleClass(h.rangeCell,g&&!u&&!o)}})}},refresh:function(){c.create.calendar()},bind:{events:function(){k.on("mousedown"+C,c.event.mousedown),k.on("touchstart"+C,c.event.mousedown),k.on("mouseup"+C,c.event.mouseup),k.on("touchend"+C,c.event.mouseup),k.on("mouseover"+C,c.event.mouseover),x.length?(x.on("input"+C,c.event.inputChange),x.on("focus"+C,c.event.inputFocus),x.on("blur"+C,c.event.inputBlur),x.on("click"+C,c.event.inputClick),x.on("keydown"+C,c.event.keydown)):k.on("keydown"+C,c.event.keydown)}},unbind:{events:function(){k.off(C),x.length&&x.off(C)}},event:{mouseover:function(t){var a=e(t.target),n=a.data(D.date),o=1===t.buttons;n&&c.set.focusDate(n,!1,!0,o)},mousedown:function(t){x.length&&t.preventDefault(),O=t.type.indexOf("touch")>=0;var a=e(t.target),n=a.data(D.date);n&&c.set.focusDate(n,!1,!0,!0)},mouseup:function(t){c.focus(),t.preventDefault(),t.stopPropagation(),O=!1;var a=e(t.target),n=a.parent();(n.data(D.date)||n.data(D.focusDate)||n.data(D.mode))&&(a=n);var o=a.data(D.date),r=a.data(D.focusDate),i=a.data(D.mode);if(o){var l=a.hasClass(h.today);c.selectDate(o,l)}else r?c.set.focusDate(r):i&&c.set.mode(i)},keydown:function(e){if(27!==e.keyCode&&9!==e.keyCode||c.popup("hide"),c.popup("is visible"))if(37===e.keyCode||38===e.keyCode||39===e.keyCode||40===e.keyCode){var t=c.get.mode(),a="day"===t?7:"hour"===t?4:3,n=37===e.keyCode?-1:38===e.keyCode?-a:39==e.keyCode?1:a;n*="minute"===t?5:1;var o=c.get.focusDate()||c.get.date()||new Date,r=o.getFullYear()+("year"===t?n:0),i=o.getMonth()+("month"===t?n:0),l=o.getDate()+("day"===t?n:0),d=o.getHours()+("hour"===t?n:0),s=o.getMinutes()+("minute"===t?n:0),u=new Date(r,i,l,d,s);"time"===f.type&&(u=c.helper.mergeDateTime(o,u)),c.helper.isDateInRange(u,t)&&c.set.focusDate(u)}else if(13===e.keyCode){var t=c.get.mode(),p=c.get.focusDate();p&&!f.isDisabled(p,t)&&c.selectDate(p),e.preventDefault(),e.stopPropagation()}38!==e.keyCode&&40!==e.keyCode||(e.preventDefault(),c.popup("show"))},inputChange:function(){var e=x.val(),t=y.date(e,f);c.set.date(t,!1)},inputFocus:function(){k.addClass(h.active)},inputBlur:function(){if(k.removeClass(h.active),f.formatInput){var e=c.get.date(),t=v.datetime(e,f);x.val(t)}},inputClick:function(){c.popup("show")}},get:{date:function(){return w.data(D.date)||null},focusDate:function(){return w.data(D.focusDate)||null},startDate:function(){var e=c.get.calendarModule(f.startCalendar);return(e?e.get.date():w.data(D.startDate))||null},endDate:function(){var e=c.get.calendarModule(f.endCalendar);return(e?e.get.date():w.data(D.endDate))||null},monthOffset:function(){return w.data(D.monthOffset)||0},mode:function(){var t=w.data(D.mode)||f.startMode,a=c.get.validModes();return e.inArray(t,a)>=0?t:"time"===f.type?"hour":"month"===f.type?"month":"year"===f.type?"year":"day"},validModes:function(){var e=[];return"time"!==f.type&&(f.disableYear&&"year"!==f.type||e.push("year"),(!f.disableMonth&&"year"!==f.type||"month"===f.type)&&e.push("month"),f.type.indexOf("date")>=0&&e.push("day")),f.type.indexOf("time")>=0&&(e.push("hour"),f.disableMinute||e.push("minute")),e},isTouch:function(){try{return a.createEvent("TouchEvent"),!0}catch(e){return!1}},calendarModule:function(t){return t?(t instanceof e||(t=w.parent().children(t).first()),t.data(M)):null}},set:{date:function(e,t,a){t=t!==!1,a=a!==!1,e=c.helper.sanitiseDate(e),e=c.helper.dateInRange(e);var o=c.get.mode(),r=v.datetime(e,f);if(a&&f.onChange.call(F,e,r,o)===!1)return!1;if(c.set.focusDate(e),f.isDisabled(e,o))return!1;var i=c.get.endDate();i&&e&&e>i&&c.set.endDate(n),c.set.dataKeyValue(D.date,e),t&&x.length&&x.val(r)},startDate:function(e,t){e=c.helper.sanitiseDate(e);var a=c.get.calendarModule(f.startCalendar);a&&a.set.date(e),c.set.dataKeyValue(D.startDate,e,t)},endDate:function(e,t){e=c.helper.sanitiseDate(e);var a=c.get.calendarModule(f.endCalendar);a&&a.set.date(e),c.set.dataKeyValue(D.endDate,e,t)},focusDate:function(e,t,a,n){e=c.helper.sanitiseDate(e),e=c.helper.dateInRange(e);var o="day"===c.get.mode(),r=c.get.focusDate();if(o&&e&&r){var i=e.getFullYear()-r.getFullYear(),l=12*i+e.getMonth()-r.getMonth();if(l){var d=c.get.monthOffset()-l;c.set.monthOffset(d,!1)}}var s=c.set.dataKeyValue(D.focusDate,e,t);a=a!==!1&&s&&t===!1||I!=n,I=n,a&&c.update.focus(n)},monthOffset:function(e,t){var a=Math.max(f.multiMonth,1);e=Math.max(1-a,Math.min(0,e)),c.set.dataKeyValue(D.monthOffset,e,t)},mode:function(e,t){c.set.dataKeyValue(D.mode,e,t)},dataKeyValue:function(e,t,a){var n=w.data(e),o=n===t||n<=t&&n>=t;return t?w.data(e,t):w.removeData(e),a=a!==!1&&!o,a&&c.create.calendar(),!o}},selectDate:function(e,t){var a=c.get.mode(),n=t||"minute"===a||f.disableMinute&&"hour"===a||"date"===f.type&&"day"===a||"month"===f.type&&"month"===a||"year"===f.type&&"year"===a;if(n){var o=c.set.date(e)===!1;if(!o&&f.closable){c.popup("hide");var r=c.get.calendarModule(f.endCalendar);r&&(r.popup("show"),r.focus())}}else{var i="year"===a?f.disableMonth?"day":"month":"month"===a?"day":"day"===a?"hour":"minute";c.set.mode(i),"hour"===a||"day"===a&&c.get.date()?c.set.date(e):c.set.focusDate(e)}},changeDate:function(e){c.set.date(e)},clear:function(){c.set.date(n)},popup:function(){return T.popup.apply(T,arguments)},focus:function(){x.length?x.focus():k.focus()},blur:function(){x.length?x.blur():k.blur()},helper:{sanitiseDate:function(e){return e?(e instanceof Date||(e=y.date(""+e,f)),isNaN(e.getTime())?n:e):n},dateDiff:function(e,t,a){a=a||"day";var n="time"===f.type,o="year"===a,r=o||"month"===a,i="minute"===a,l=i||"hour"===a;return e=new Date(n?2e3:e.getFullYear(),n?0:o?0:e.getMonth(),n?1:r?1:e.getDate(),l?e.getHours():0,i?5*Math.floor(e.getMinutes()/5):0),t=new Date(n?2e3:t.getFullYear(),n?0:o?0:t.getMonth(),n?1:r?1:t.getDate(),l?t.getHours():0,i?5*Math.floor(t.getMinutes()/5):0),t.getTime()-e.getTime()},dateEqual:function(e,t,a){return!!e&&!!t&&0===c.helper.dateDiff(e,t,a)},isDateInRange:function(e,t,a,n){if(!a&&!n){var o=c.get.startDate();a=o&&f.minDate?new Date(Math.max(o,f.minDate)):o||f.minDate,n=f.maxDate}return a=a&&new Date(a.getFullYear(),a.getMonth(),a.getDate(),a.getHours(),5*Math.ceil(a.getMinutes()/5)),!(!e||a&&c.helper.dateDiff(e,a,t)>0||n&&c.helper.dateDiff(n,e,t)>0)},dateInRange:function(e,t,a){if(!t&&!a){var n=c.get.startDate();t=n&&f.minDate?new Date(Math.max(n,f.minDate)):n||f.minDate,a=f.maxDate}t=t&&new Date(t.getFullYear(),t.getMonth(),t.getDate(),t.getHours(),5*Math.ceil(t.getMinutes()/5));var o="time"===f.type;return e?t&&c.helper.dateDiff(e,t,"minute")>0?o?c.helper.mergeDateTime(e,t):t:a&&c.helper.dateDiff(a,e,"minute")>0?o?c.helper.mergeDateTime(e,a):a:e:e},mergeDateTime:function(e,t){return e&&t?new Date(e.getFullYear(),e.getMonth(),e.getDate(),t.getHours(),t.getMinutes()):t}},setting:function(t,a){if(c.debug("Changing setting",t,a),e.isPlainObject(t))e.extend(!0,f,t);else{if(a===n)return f[t];e.isPlainObject(f[t])?e.extend(!0,f[t],a):f[t]=a}},internal:function(t,a){return c.debug("Changing internal",t,a),a===n?c[t]:void(e.isPlainObject(t)?e.extend(!0,c,t):c[t]=a)},debug:function(){!f.silent&&f.debug&&(f.performance?c.performance.log(arguments):(c.debug=Function.prototype.bind.call(console.info,console,f.name+":"),c.debug.apply(console,arguments)))},verbose:function(){!f.silent&&f.verbose&&f.debug&&(f.performance?c.performance.log(arguments):(c.verbose=Function.prototype.bind.call(console.info,console,f.name+":"),c.verbose.apply(console,arguments)))},error:function(){f.silent||(c.error=Function.prototype.bind.call(console.error,console,f.name+":"),c.error.apply(console,arguments))},performance:{log:function(e){var t,a,n;f.performance&&(t=(new Date).getTime(),n=l||t,a=t-n,l=t,d.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:F,"Execution Time":a})),clearTimeout(c.performance.timer),c.performance.timer=setTimeout(c.performance.display,500)},display:function(){var t=f.name+":",a=0;l=!1,clearTimeout(c.performance.timer),e.each(d,function(e,t){a+=t["Execution Time"]}),t+=" "+a+"ms",i&&(t+=" '"+i+"'"),(console.group!==n||console.table!==n)&&d.length>0&&(console.groupCollapsed(t),console.table?console.table(d):e.each(d,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),d=[]}},invoke:function(t,a,r){var i,l,d,s=H;return a=a||p,r=F||r,"string"==typeof t&&s!==n&&(t=t.split(/[\. ]/),i=t.length-1,e.each(t,function(a,o){var r=a!=i?o+t[a+1].charAt(0).toUpperCase()+t[a+1].slice(1):t;if(e.isPlainObject(s[r])&&a!=i)s=s[r];else{if(s[r]!==n)return l=s[r],!1;if(!e.isPlainObject(s[o])||a==i)return s[o]!==n?(l=s[o],!1):(c.error(b.method,t),!1);s=s[o]}})),e.isFunction(l)?d=l.apply(r,a):l!==n&&(d=l),e.isArray(o)?o.push(d):o!==n?o=[o,d]:d!==n&&(o=d),l}},u?(H===n&&c.initialize(),c.invoke(s)):(H!==n&&H.invoke("destroy"),c.initialize())}),o!==n?o:this},e.fn.calendar.settings={name:"Calendar",namespace:"calendar",silent:!1,debug:!1,verbose:!1,performance:!1,type:"datetime",firstDayOfWeek:0,constantHeight:!0,today:!1,closable:!0,monthFirst:!0,touchReadonly:!0,inline:!1,on:null,initialDate:null,startMode:!1,minDate:null,maxDate:null,ampm:!0,disableYear:!1,disableMonth:!1,disableMinute:!1,formatInput:!0,startCalendar:null,endCalendar:null,multiMonth:1,popupOptions:{position:"bottom left",lastResort:"bottom left",prefer:"opposite",hideOnScroll:!1},text:{days:["S","M","T","W","T","F","S"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],today:"Today",now:"Now",am:"AM",pm:"PM"},formatter:{header:function(e,t,a){return"year"===t?a.formatter.yearHeader(e,a):"month"===t?a.formatter.monthHeader(e,a):"day"===t?a.formatter.dayHeader(e,a):"hour"===t?a.formatter.hourHeader(e,a):a.formatter.minuteHeader(e,a)},yearHeader:function(e,t){var a=10*Math.ceil(e.getFullYear()/10);return a-9+" - "+(a+2)},monthHeader:function(e,t){return e.getFullYear()},dayHeader:function(e,t){var a=t.text.months[e.getMonth()],n=e.getFullYear();return a+" "+n},hourHeader:function(e,t){return t.formatter.date(e,t)},minuteHeader:function(e,t){return t.formatter.date(e,t)},dayColumnHeader:function(e,t){return t.text.days[e]},datetime:function(e,t){if(!e)return"";var a="time"===t.type?"":t.formatter.date(e,t),n=t.type.indexOf("time")<0?"":t.formatter.time(e,t,!1),o="datetime"===t.type?" ":"";return a+o+n},date:function(e,t){if(!e)return"";var a=e.getDate(),n=t.text.months[e.getMonth()],o=e.getFullYear();return"year"===t.type?o:"month"===t.type?n+" "+o:(t.monthFirst?n+" "+a:a+" "+n)+", "+o},time:function(e,t,a){if(!e)return"";var n=e.getHours(),o=e.getMinutes(),r="";return t.ampm&&(r=" "+(n<12?t.text.am:t.text.pm),n=0===n?12:n>12?n-12:n),n+":"+(o<10?"0":"")+o+r},today:function(e){return"date"===e.type?e.text.today:e.text.now},cell:function(e,t,a){}},parser:{date:function(t,a){if(!t)return null;if(t=(""+t).trim().toLowerCase(),0===t.length)return null;var o,r,i,l=-1,d=-1,s=-1,u=-1,p=-1,c=n,f="time"===a.type,h=a.type.indexOf("time")<0,g=t.split(a.regExp.dateWords),m=t.split(a.regExp.dateNumbers);if(!h)for(c=e.inArray(a.text.am.toLowerCase(),g)>=0||!(e.inArray(a.text.pm.toLowerCase(),g)>=0)&&n,o=0;o=0){if(d<0||l<0){var y=v.split(":");for(i=0;i=0)break}}for(o=0;o59){p=r,m.splice(o,1);break}if(u<0)for(o=0;o1||a.monthFirst?o:1===o?0:1,r=parseInt(m[i]),!isNaN(r)&&1<=r&&r<=12){u=r,m.splice(i,1);break}for(o=0;o=0;o--)if(r=parseInt(m[o]),!isNaN(r)){r<99&&(r+=2e3),p=r,m.splice(o,1);break}}if(!h){if(d<0)for(o=0;o 1) { + attributes = extend({ + path: '/' + }, api.defaults, attributes); + + if (typeof attributes.expires === 'number') { + var expires = new Date(); + expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5); + attributes.expires = expires; + } + + // We're using "expires" because "max-age" is not supported by IE + attributes.expires = attributes.expires ? attributes.expires.toUTCString() : ''; + + try { + result = JSON.stringify(value); + if (/^[\{\[]/.test(result)) { + value = result; + } + } catch (e) {} + + if (!converter.write) { + value = encodeURIComponent(String(value)) + .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent); + } else { + value = converter.write(value, key); + } + + key = encodeURIComponent(String(key)); + key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent); + key = key.replace(/[\(\)]/g, escape); + + var stringifiedAttributes = ''; + + for (var attributeName in attributes) { + if (!attributes[attributeName]) { + continue; + } + stringifiedAttributes += '; ' + attributeName; + if (attributes[attributeName] === true) { + continue; + } + stringifiedAttributes += '=' + attributes[attributeName]; + } + return (document.cookie = key + '=' + value + stringifiedAttributes); + } + + // Read + + if (!key) { + result = {}; + } + + // To prevent the for loop in the first place assign an empty array + // in case there are no cookies at all. Also prevents odd result when + // calling "get()" + var cookies = document.cookie ? document.cookie.split('; ') : []; + var rdecode = /(%[0-9A-Z]{2})+/g; + var i = 0; + + for (; i < cookies.length; i++) { + var parts = cookies[i].split('='); + var cookie = parts.slice(1).join('='); + + if (cookie.charAt(0) === '"') { + cookie = cookie.slice(1, -1); + } + + try { + var name = parts[0].replace(rdecode, decodeURIComponent); + cookie = converter.read ? + converter.read(cookie, name) : converter(cookie, name) || + cookie.replace(rdecode, decodeURIComponent); + + if (this.json) { + try { + cookie = JSON.parse(cookie); + } catch (e) {} + } + + if (key === name) { + result = cookie; + break; + } + + if (!key) { + result[name] = cookie; + } + } catch (e) {} + } + + return result; + } + + api.set = api; + api.get = function (key) { + return api.call(api, key); + }; + api.getJSON = function () { + return api.apply({ + json: true + }, [].slice.call(arguments)); + }; + api.defaults = {}; + + api.remove = function (key, attributes) { + api(key, '', extend(attributes, { + expires: -1 + })); + }; + + api.withConverter = init; + + return api; + } + + return init(function () {}); +})); diff --git a/public/plugins/datatable/dataTables.semanticui.css b/public/plugins/datatable/dataTables.semanticui.css new file mode 100755 index 0000000..28305cb --- /dev/null +++ b/public/plugins/datatable/dataTables.semanticui.css @@ -0,0 +1,71 @@ +/* + * Styling for DataTables with Semantic UI + */ +table.dataTable.table { + margin: 0; +} +table.dataTable.table thead th, +table.dataTable.table thead td { + position: relative; +} +table.dataTable.table thead th.sorting:after, table.dataTable.table thead th.sorting_asc:after, table.dataTable.table thead th.sorting_desc:after, +table.dataTable.table thead td.sorting:after, +table.dataTable.table thead td.sorting_asc:after, +table.dataTable.table thead td.sorting_desc:after { + position: absolute; + top: 12px; + right: 8px; + display: block; + font-family: Icons; +} +table.dataTable.table thead th.sorting:after, +table.dataTable.table thead td.sorting:after { + content: "\f0dc"; + color: #ddd; + font-size: 0.8em; + padding-top: 0.12em; +} +table.dataTable.table thead th.sorting_asc:after, +table.dataTable.table thead td.sorting_asc:after { + content: "\f0de"; +} +table.dataTable.table thead th.sorting_desc:after, +table.dataTable.table thead td.sorting_desc:after { + content: "\f0dd"; +} +table.dataTable.table td, +table.dataTable.table th { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +table.dataTable.table td.dataTables_empty, +table.dataTable.table th.dataTables_empty { + text-align: center; +} +table.dataTable.table.nowrap th, +table.dataTable.table.nowrap td { + white-space: nowrap; +} + +div.dataTables_wrapper div.dataTables_length .ui.selection.dropdown { + min-width: 0; +} +div.dataTables_wrapper div.dataTables_filter input { + margin-left: 0.5em; +} +div.dataTables_wrapper div.dataTables_info { + padding-top: 13px; + white-space: nowrap; +} +div.dataTables_wrapper div.dataTables_processing { + position: absolute; + top: 50%; + left: 50%; + width: 200px; + margin-left: -100px; + text-align: center; +} +div.dataTables_wrapper div.row.dt-table { + padding: 0; +} diff --git a/public/plugins/datatable/dataTables.semanticui.js b/public/plugins/datatable/dataTables.semanticui.js new file mode 100755 index 0000000..97f797e --- /dev/null +++ b/public/plugins/datatable/dataTables.semanticui.js @@ -0,0 +1,208 @@ +/*! DataTables Bootstrap 3 integration + * ©2011-2015 SpryMedia Ltd - datatables.net/license + */ + +/** + * DataTables integration for Bootstrap 3. This requires Bootstrap 3 and + * DataTables 1.10 or newer. + * + * This file sets the defaults and adds options to DataTables to style its + * controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap + * for further information. + */ +(function( factory ){ + if ( typeof define === 'function' && define.amd ) { + // AMD + define( ['jquery', 'datatables.net'], function ( $ ) { + return factory( $, window, document ); + } ); + } + else if ( typeof exports === 'object' ) { + // CommonJS + module.exports = function (root, $) { + if ( ! root ) { + root = window; + } + + if ( ! $ || ! $.fn.dataTable ) { + // Require DataTables, which attaches to jQuery, including + // jQuery if needed and have a $ property so we can access the + // jQuery object that is used + $ = require('datatables.net')(root, $).$; + } + + return factory( $, root, root.document ); + }; + } + else { + // Browser + factory( jQuery, window, document ); + } +}(function( $, window, document, undefined ) { +'use strict'; +var DataTable = $.fn.dataTable; + + +/* Set the defaults for DataTables initialisation */ +$.extend( true, DataTable.defaults, { + dom: + "<'ui grid'"+ + "<'row'"+ + "<'eight wide column'l>"+ + "<'right aligned eight wide column'f>"+ + ">"+ + "<'row dt-table'"+ + "<'sixteen wide column'tr>"+ + ">"+ + "<'row'"+ + "<'seven wide column'i>"+ + "<'right aligned nine wide column'p>"+ + ">"+ + ">", + renderer: 'semanticUI' +} ); + + +/* Default class modification */ +$.extend( DataTable.ext.classes, { + sWrapper: "dataTables_wrapper dt-semanticUI", + sFilter: "dataTables_filter ui input", + sProcessing: "dataTables_processing ui segment", + sPageButton: "paginate_button item" +} ); + + +/* Bootstrap paging button renderer */ +DataTable.ext.renderer.pageButton.semanticUI = function ( settings, host, idx, buttons, page, pages ) { + var api = new DataTable.Api( settings ); + var classes = settings.oClasses; + var lang = settings.oLanguage.oPaginate; + var aria = settings.oLanguage.oAria.paginate || {}; + var btnDisplay, btnClass, counter=0; + + var attach = function( container, buttons ) { + var i, ien, node, button; + var clickHandler = function ( e ) { + e.preventDefault(); + if ( !$(e.currentTarget).hasClass('disabled') && api.page() != e.data.action ) { + api.page( e.data.action ).draw( 'page' ); + } + }; + + for ( i=0, ien=buttons.length ; i 0 ? + '' : ' disabled'); + break; + + case 'previous': + btnDisplay = lang.sPrevious; + btnClass = button + (page > 0 ? + '' : ' disabled'); + break; + + case 'next': + btnDisplay = lang.sNext; + btnClass = button + (page < pages-1 ? + '' : ' disabled'); + break; + + case 'last': + btnDisplay = lang.sLast; + btnClass = button + (page < pages-1 ? + '' : ' disabled'); + break; + + default: + btnDisplay = button + 1; + btnClass = page === button ? + 'active' : ''; + break; + } + + var tag = btnClass.indexOf( 'disabled' ) === -1 ? + 'a' : + 'div'; + + if ( btnDisplay ) { + node = $('<'+tag+'>', { + 'class': classes.sPageButton+' '+btnClass, + 'id': idx === 0 && typeof button === 'string' ? + settings.sTableId +'_'+ button : + null, + 'href': '#', + 'aria-controls': settings.sTableId, + 'aria-label': aria[ button ], + 'data-dt-idx': counter, + 'tabindex': settings.iTabIndex + } ) + .html( btnDisplay ) + .appendTo( container ); + + settings.oApi._fnBindAction( + node, {action: button}, clickHandler + ); + + counter++; + } + } + } + }; + + // IE9 throws an 'unknown error' if document.activeElement is used + // inside an iframe or frame. + var activeEl; + + try { + // Because this approach is destroying and recreating the paging + // elements, focus is lost on the select button which is bad for + // accessibility. So we want to restore focus once the draw has + // completed + activeEl = $(host).find(document.activeElement).data('dt-idx'); + } + catch (e) {} + + attach( + $(host).empty().html('', { + 'valign': 'top', + 'colSpan': _fnVisbleColumns( oSettings ), + 'class': oSettings.oClasses.sRowEmpty + } ).html( sZero ) )[0]; + } + + /* Header and footer callbacks */ + _fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0], + _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] ); + + _fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0], + _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] ); + + var body = $(oSettings.nTBody); + + body.children().detach(); + body.append( $(anRows) ); + + /* Call all required callback functions for the end of a draw */ + _fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] ); + + /* Draw is complete, sorting and filtering must be as well */ + oSettings.bSorted = false; + oSettings.bFiltered = false; + oSettings.bDrawing = false; + } + + + /** + * Redraw the table - taking account of the various features which are enabled + * @param {object} oSettings dataTables settings object + * @param {boolean} [holdPosition] Keep the current paging position. By default + * the paging is reset to the first page + * @memberof DataTable#oApi + */ + function _fnReDraw( settings, holdPosition ) + { + var + features = settings.oFeatures, + sort = features.bSort, + filter = features.bFilter; + + if ( sort ) { + _fnSort( settings ); + } + + if ( filter ) { + _fnFilterComplete( settings, settings.oPreviousSearch ); + } + else { + // No filtering, so we want to just use the display master + settings.aiDisplay = settings.aiDisplayMaster.slice(); + } + + if ( holdPosition !== true ) { + settings._iDisplayStart = 0; + } + + // Let any modules know about the draw hold position state (used by + // scrolling internally) + settings._drawHold = holdPosition; + + _fnDraw( settings ); + + settings._drawHold = false; + } + + + /** + * Add the options to the page HTML for the table + * @param {object} oSettings dataTables settings object + * @memberof DataTable#oApi + */ + function _fnAddOptionsHtml ( oSettings ) + { + var classes = oSettings.oClasses; + var table = $(oSettings.nTable); + var holding = $('
').insertBefore( table ); // Holding element for speed + var features = oSettings.oFeatures; + + // All DataTables are wrapped in a div + var insert = $('
', { + id: oSettings.sTableId+'_wrapper', + 'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter) + } ); + + oSettings.nHolding = holding[0]; + oSettings.nTableWrapper = insert[0]; + oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling; + + /* Loop over the user set positioning and place the elements as needed */ + var aDom = oSettings.sDom.split(''); + var featureNode, cOption, nNewNode, cNext, sAttr, j; + for ( var i=0 ; i')[0]; + + /* Check to see if we should append an id and/or a class name to the container */ + cNext = aDom[i+1]; + if ( cNext == "'" || cNext == '"' ) + { + sAttr = ""; + j = 2; + while ( aDom[i+j] != cNext ) + { + sAttr += aDom[i+j]; + j++; + } + + /* Replace jQuery UI constants @todo depreciated */ + if ( sAttr == "H" ) + { + sAttr = classes.sJUIHeader; + } + else if ( sAttr == "F" ) + { + sAttr = classes.sJUIFooter; + } + + /* The attribute can be in the format of "#id.class", "#id" or "class" This logic + * breaks the string into parts and applies them as needed + */ + if ( sAttr.indexOf('.') != -1 ) + { + var aSplit = sAttr.split('.'); + nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1); + nNewNode.className = aSplit[1]; + } + else if ( sAttr.charAt(0) == "#" ) + { + nNewNode.id = sAttr.substr(1, sAttr.length-1); + } + else + { + nNewNode.className = sAttr; + } + + i += j; /* Move along the position array */ + } + + insert.append( nNewNode ); + insert = $(nNewNode); + } + else if ( cOption == '>' ) + { + /* End container div */ + insert = insert.parent(); + } + // @todo Move options into their own plugins? + else if ( cOption == 'l' && features.bPaginate && features.bLengthChange ) + { + /* Length */ + featureNode = _fnFeatureHtmlLength( oSettings ); + } + else if ( cOption == 'f' && features.bFilter ) + { + /* Filter */ + featureNode = _fnFeatureHtmlFilter( oSettings ); + } + else if ( cOption == 'r' && features.bProcessing ) + { + /* pRocessing */ + featureNode = _fnFeatureHtmlProcessing( oSettings ); + } + else if ( cOption == 't' ) + { + /* Table */ + featureNode = _fnFeatureHtmlTable( oSettings ); + } + else if ( cOption == 'i' && features.bInfo ) + { + /* Info */ + featureNode = _fnFeatureHtmlInfo( oSettings ); + } + else if ( cOption == 'p' && features.bPaginate ) + { + /* Pagination */ + featureNode = _fnFeatureHtmlPaginate( oSettings ); + } + else if ( DataTable.ext.feature.length !== 0 ) + { + /* Plug-in features */ + var aoFeatures = DataTable.ext.feature; + for ( var k=0, kLen=aoFeatures.length ; k'; + + var str = language.sSearch; + str = str.match(/_INPUT_/) ? + str.replace('_INPUT_', input) : + str+input; + + var filter = $('
', { + 'id': ! features.f ? tableId+'_filter' : null, + 'class': classes.sFilter + } ) + .append( $('
').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] : + data.anCells[ colIdx ]; + } + + + /** + * Get the maximum strlen for each data column + * @param {object} settings dataTables settings object + * @param {int} colIdx column of interest + * @returns {string} max string length for each column + * @memberof DataTable#oApi + */ + function _fnGetMaxLenString( settings, colIdx ) + { + var s, max=-1, maxIdx = -1; + + for ( var i=0, ien=settings.aoData.length ; i max ) { + max = s.length; + maxIdx = i; + } + } + + return maxIdx; + } + + + /** + * Append a CSS unit (only if required) to a string + * @param {string} value to css-ify + * @returns {string} value with css unit + * @memberof DataTable#oApi + */ + function _fnStringToCss( s ) + { + if ( s === null ) { + return '0px'; + } + + if ( typeof s == 'number' ) { + return s < 0 ? + '0px' : + s+'px'; + } + + // Check it has a unit character already + return s.match(/\d$/) ? + s+'px' : + s; + } + + + + function _fnSortFlatten ( settings ) + { + var + i, iLen, k, kLen, + aSort = [], + aiOrig = [], + aoColumns = settings.aoColumns, + aDataSort, iCol, sType, srcCol, + fixed = settings.aaSortingFixed, + fixedObj = $.isPlainObject( fixed ), + nestedSort = [], + add = function ( a ) { + if ( a.length && ! $.isArray( a[0] ) ) { + // 1D array + nestedSort.push( a ); + } + else { + // 2D array + $.merge( nestedSort, a ); + } + }; + + // Build the sort array, with pre-fix and post-fix options if they have been + // specified + if ( $.isArray( fixed ) ) { + add( fixed ); + } + + if ( fixedObj && fixed.pre ) { + add( fixed.pre ); + } + + add( settings.aaSorting ); + + if (fixedObj && fixed.post ) { + add( fixed.post ); + } + + for ( i=0 ; iy ? 1 : 0; + if ( test !== 0 ) { + return sort.dir === 'asc' ? test : -test; + } + } + + x = aiOrig[a]; + y = aiOrig[b]; + return xy ? 1 : 0; + } ); + } + else { + // Depreciated - remove in 1.11 (providing a plug-in option) + // Not all sort types have formatting methods, so we have to call their sorting + // methods. + displayMaster.sort( function ( a, b ) { + var + x, y, k, l, test, sort, fn, + len=aSort.length, + dataA = aoData[a]._aSortData, + dataB = aoData[b]._aSortData; + + for ( k=0 ; ky ? 1 : 0; + } ); + } + } + + /* Tell the draw function that we have sorted the data */ + oSettings.bSorted = true; + } + + + function _fnSortAria ( settings ) + { + var label; + var nextSort; + var columns = settings.aoColumns; + var aSort = _fnSortFlatten( settings ); + var oAria = settings.oLanguage.oAria; + + // ARIA attributes - need to loop all columns, to update all (removing old + // attributes as needed) + for ( var i=0, iLen=columns.length ; i/g, "" ); + var th = col.nTh; + + // IE7 is throwing an error when setting these properties with jQuery's + // attr() and removeAttr() methods... + th.removeAttribute('aria-sort'); + + /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */ + if ( col.bSortable ) { + if ( aSort.length > 0 && aSort[0].col == i ) { + th.setAttribute('aria-sort', aSort[0].dir=="asc" ? "ascending" : "descending" ); + nextSort = asSorting[ aSort[0].index+1 ] || asSorting[0]; + } + else { + nextSort = asSorting[0]; + } + + label = sTitle + ( nextSort === "asc" ? + oAria.sSortAscending : + oAria.sSortDescending + ); + } + else { + label = sTitle; + } + + th.setAttribute('aria-label', label); + } + } + + + /** + * Function to run on user sort request + * @param {object} settings dataTables settings object + * @param {node} attachTo node to attach the handler to + * @param {int} colIdx column sorting index + * @param {boolean} [append=false] Append the requested sort to the existing + * sort if true (i.e. multi-column sort) + * @param {function} [callback] callback function + * @memberof DataTable#oApi + */ + function _fnSortListener ( settings, colIdx, append, callback ) + { + var col = settings.aoColumns[ colIdx ]; + var sorting = settings.aaSorting; + var asSorting = col.asSorting; + var nextSortIdx; + var next = function ( a, overflow ) { + var idx = a._idx; + if ( idx === undefined ) { + idx = $.inArray( a[1], asSorting ); + } + + return idx+1 < asSorting.length ? + idx+1 : + overflow ? + null : + 0; + }; + + // Convert to 2D array if needed + if ( typeof sorting[0] === 'number' ) { + sorting = settings.aaSorting = [ sorting ]; + } + + // If appending the sort then we are multi-column sorting + if ( append && settings.oFeatures.bSortMulti ) { + // Are we already doing some kind of sort on this column? + var sortIdx = $.inArray( colIdx, _pluck(sorting, '0') ); + + if ( sortIdx !== -1 ) { + // Yes, modify the sort + nextSortIdx = next( sorting[sortIdx], true ); + + if ( nextSortIdx === null && sorting.length === 1 ) { + nextSortIdx = 0; // can't remove sorting completely + } + + if ( nextSortIdx === null ) { + sorting.splice( sortIdx, 1 ); + } + else { + sorting[sortIdx][1] = asSorting[ nextSortIdx ]; + sorting[sortIdx]._idx = nextSortIdx; + } + } + else { + // No sort on this column yet + sorting.push( [ colIdx, asSorting[0], 0 ] ); + sorting[sorting.length-1]._idx = 0; + } + } + else if ( sorting.length && sorting[0][0] == colIdx ) { + // Single column - already sorting on this column, modify the sort + nextSortIdx = next( sorting[0] ); + + sorting.length = 1; + sorting[0][1] = asSorting[ nextSortIdx ]; + sorting[0]._idx = nextSortIdx; + } + else { + // Single column - sort only on this column + sorting.length = 0; + sorting.push( [ colIdx, asSorting[0] ] ); + sorting[0]._idx = 0; + } + + // Run the sort by calling a full redraw + _fnReDraw( settings ); + + // callback used for async user interaction + if ( typeof callback == 'function' ) { + callback( settings ); + } + } + + + /** + * Attach a sort handler (click) to a node + * @param {object} settings dataTables settings object + * @param {node} attachTo node to attach the handler to + * @param {int} colIdx column sorting index + * @param {function} [callback] callback function + * @memberof DataTable#oApi + */ + function _fnSortAttachListener ( settings, attachTo, colIdx, callback ) + { + var col = settings.aoColumns[ colIdx ]; + + _fnBindAction( attachTo, {}, function (e) { + /* If the column is not sortable - don't to anything */ + if ( col.bSortable === false ) { + return; + } + + // If processing is enabled use a timeout to allow the processing + // display to be shown - otherwise to it synchronously + if ( settings.oFeatures.bProcessing ) { + _fnProcessingDisplay( settings, true ); + + setTimeout( function() { + _fnSortListener( settings, colIdx, e.shiftKey, callback ); + + // In server-side processing, the draw callback will remove the + // processing display + if ( _fnDataSource( settings ) !== 'ssp' ) { + _fnProcessingDisplay( settings, false ); + } + }, 0 ); + } + else { + _fnSortListener( settings, colIdx, e.shiftKey, callback ); + } + } ); + } + + + /** + * Set the sorting classes on table's body, Note: it is safe to call this function + * when bSort and bSortClasses are false + * @param {object} oSettings dataTables settings object + * @memberof DataTable#oApi + */ + function _fnSortingClasses( settings ) + { + var oldSort = settings.aLastSort; + var sortClass = settings.oClasses.sSortColumn; + var sort = _fnSortFlatten( settings ); + var features = settings.oFeatures; + var i, ien, colIdx; + + if ( features.bSort && features.bSortClasses ) { + // Remove old sorting classes + for ( i=0, ien=oldSort.length ; i 0 && state.time < +new Date() - (duration*1000) ) { + return; + } + + // Number of columns have changed - all bets are off, no restore of settings + if ( columns.length !== state.columns.length ) { + return; + } + + // Store the saved state so it might be accessed at any time + settings.oLoadedState = $.extend( true, {}, state ); + + // Restore key features - todo - for 1.11 this needs to be done by + // subscribed events + if ( state.start !== undefined ) { + settings._iDisplayStart = state.start; + settings.iInitDisplayStart = state.start; + } + if ( state.length !== undefined ) { + settings._iDisplayLength = state.length; + } + + // Order + if ( state.order !== undefined ) { + settings.aaSorting = []; + $.each( state.order, function ( i, col ) { + settings.aaSorting.push( col[0] >= columns.length ? + [ 0, col[1] ] : + col + ); + } ); + } + + // Search + if ( state.search !== undefined ) { + $.extend( settings.oPreviousSearch, _fnSearchToHung( state.search ) ); + } + + // Columns + for ( i=0, ien=state.columns.length ; i= end ) + { + start = end - len; + } + + // Keep the start record on the current page + start -= (start % len); + + if ( len === -1 || start < 0 ) + { + start = 0; + } + + settings._iDisplayStart = start; + } + + + function _fnRenderer( settings, type ) + { + var renderer = settings.renderer; + var host = DataTable.ext.renderer[type]; + + if ( $.isPlainObject( renderer ) && renderer[type] ) { + // Specific renderer for this type. If available use it, otherwise use + // the default. + return host[renderer[type]] || host._; + } + else if ( typeof renderer === 'string' ) { + // Common renderer - if there is one available for this type use it, + // otherwise use the default + return host[renderer] || host._; + } + + // Use the default + return host._; + } + + + /** + * Detect the data source being used for the table. Used to simplify the code + * a little (ajax) and to make it compress a little smaller. + * + * @param {object} settings dataTables settings object + * @returns {string} Data source + * @memberof DataTable#oApi + */ + function _fnDataSource ( settings ) + { + if ( settings.oFeatures.bServerSide ) { + return 'ssp'; + } + else if ( settings.ajax || settings.sAjaxSource ) { + return 'ajax'; + } + return 'dom'; + } + + + DataTable = function( options ) + { + /** + * Perform a jQuery selector action on the table's TR elements (from the tbody) and + * return the resulting jQuery object. + * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on + * @param {object} [oOpts] Optional parameters for modifying the rows to be included + * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter + * criterion ("applied") or all TR elements (i.e. no filter). + * @param {string} [oOpts.order=current] Order of the TR elements in the processed array. + * Can be either 'current', whereby the current sorting of the table is used, or + * 'original' whereby the original order the data was read into the table is used. + * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page + * ("current") or not ("all"). If 'current' is given, then order is assumed to be + * 'current' and filter is 'applied', regardless of what they might be given as. + * @returns {object} jQuery object, filtered by the given selector. + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Highlight every second row + * oTable.$('tr:odd').css('backgroundColor', 'blue'); + * } ); + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Filter to rows with 'Webkit' in them, add a background colour and then + * // remove the filter, thus highlighting the 'Webkit' rows only. + * oTable.fnFilter('Webkit'); + * oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue'); + * oTable.fnFilter(''); + * } ); + */ + this.$ = function ( sSelector, oOpts ) + { + return this.api(true).$( sSelector, oOpts ); + }; + + + /** + * Almost identical to $ in operation, but in this case returns the data for the matched + * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes + * rather than any descendants, so the data can be obtained for the row/cell. If matching + * rows are found, the data returned is the original data array/object that was used to + * create the row (or a generated array if from a DOM source). + * + * This method is often useful in-combination with $ where both functions are given the + * same parameters and the array indexes will match identically. + * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on + * @param {object} [oOpts] Optional parameters for modifying the rows to be included + * @param {string} [oOpts.filter=none] Select elements that meet the current filter + * criterion ("applied") or all elements (i.e. no filter). + * @param {string} [oOpts.order=current] Order of the data in the processed array. + * Can be either 'current', whereby the current sorting of the table is used, or + * 'original' whereby the original order the data was read into the table is used. + * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page + * ("current") or not ("all"). If 'current' is given, then order is assumed to be + * 'current' and filter is 'applied', regardless of what they might be given as. + * @returns {array} Data for the matched elements. If any elements, as a result of the + * selector, were not TR, TD or TH elements in the DataTable, they will have a null + * entry in the array. + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Get the data from the first row in the table + * var data = oTable._('tr:first'); + * + * // Do something useful with the data + * alert( "First cell is: "+data[0] ); + * } ); + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Filter to 'Webkit' and get all data for + * oTable.fnFilter('Webkit'); + * var data = oTable._('tr', {"search": "applied"}); + * + * // Do something with the data + * alert( data.length+" rows matched the search" ); + * } ); + */ + this._ = function ( sSelector, oOpts ) + { + return this.api(true).rows( sSelector, oOpts ).data(); + }; + + + /** + * Create a DataTables Api instance, with the currently selected tables for + * the Api's context. + * @param {boolean} [traditional=false] Set the API instance's context to be + * only the table referred to by the `DataTable.ext.iApiIndex` option, as was + * used in the API presented by DataTables 1.9- (i.e. the traditional mode), + * or if all tables captured in the jQuery object should be used. + * @return {DataTables.Api} + */ + this.api = function ( traditional ) + { + return traditional ? + new _Api( + _fnSettingsFromNode( this[ _ext.iApiIndex ] ) + ) : + new _Api( this ); + }; + + + /** + * Add a single new row or multiple rows of data to the table. Please note + * that this is suitable for client-side processing only - if you are using + * server-side processing (i.e. "bServerSide": true), then to add data, you + * must add it to the data source, i.e. the server-side, through an Ajax call. + * @param {array|object} data The data to be added to the table. This can be: + *
    + *
  • 1D array of data - add a single row with the data provided
  • + *
  • 2D array of arrays - add multiple rows in a single call
  • + *
  • object - data object when using mData
  • + *
  • array of objects - multiple data objects when using mData
  • + *
+ * @param {bool} [redraw=true] redraw the table or not + * @returns {array} An array of integers, representing the list of indexes in + * aoData ({@link DataTable.models.oSettings}) that have been added to + * the table. + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * // Global var for counter + * var giCount = 2; + * + * $(document).ready(function() { + * $('#example').dataTable(); + * } ); + * + * function fnClickAddRow() { + * $('#example').dataTable().fnAddData( [ + * giCount+".1", + * giCount+".2", + * giCount+".3", + * giCount+".4" ] + * ); + * + * giCount++; + * } + */ + this.fnAddData = function( data, redraw ) + { + var api = this.api( true ); + + /* Check if we want to add multiple rows or not */ + var rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ? + api.rows.add( data ) : + api.row.add( data ); + + if ( redraw === undefined || redraw ) { + api.draw(); + } + + return rows.flatten().toArray(); + }; + + + /** + * This function will make DataTables recalculate the column sizes, based on the data + * contained in the table and the sizes applied to the columns (in the DOM, CSS or + * through the sWidth parameter). This can be useful when the width of the table's + * parent element changes (for example a window resize). + * @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable( { + * "sScrollY": "200px", + * "bPaginate": false + * } ); + * + * $(window).bind('resize', function () { + * oTable.fnAdjustColumnSizing(); + * } ); + * } ); + */ + this.fnAdjustColumnSizing = function ( bRedraw ) + { + var api = this.api( true ).columns.adjust(); + var settings = api.settings()[0]; + var scroll = settings.oScroll; + + if ( bRedraw === undefined || bRedraw ) { + api.draw( false ); + } + else if ( scroll.sX !== "" || scroll.sY !== "" ) { + /* If not redrawing, but scrolling, we want to apply the new column sizes anyway */ + _fnScrollDraw( settings ); + } + }; + + + /** + * Quickly and simply clear a table + * @param {bool} [bRedraw=true] redraw the table or not + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...) + * oTable.fnClearTable(); + * } ); + */ + this.fnClearTable = function( bRedraw ) + { + var api = this.api( true ).clear(); + + if ( bRedraw === undefined || bRedraw ) { + api.draw(); + } + }; + + + /** + * The exact opposite of 'opening' a row, this function will close any rows which + * are currently 'open'. + * @param {node} nTr the table row to 'close' + * @returns {int} 0 on success, or 1 if failed (can't find the row) + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable; + * + * // 'open' an information row when a row is clicked on + * $('#example tbody tr').click( function () { + * if ( oTable.fnIsOpen(this) ) { + * oTable.fnClose( this ); + * } else { + * oTable.fnOpen( this, "Temporary row opened", "info_row" ); + * } + * } ); + * + * oTable = $('#example').dataTable(); + * } ); + */ + this.fnClose = function( nTr ) + { + this.api( true ).row( nTr ).child.hide(); + }; + + + /** + * Remove a row for the table + * @param {mixed} target The index of the row from aoData to be deleted, or + * the TR element you want to delete + * @param {function|null} [callBack] Callback function + * @param {bool} [redraw=true] Redraw the table or not + * @returns {array} The row that was deleted + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Immediately remove the first row + * oTable.fnDeleteRow( 0 ); + * } ); + */ + this.fnDeleteRow = function( target, callback, redraw ) + { + var api = this.api( true ); + var rows = api.rows( target ); + var settings = rows.settings()[0]; + var data = settings.aoData[ rows[0][0] ]; + + rows.remove(); + + if ( callback ) { + callback.call( this, settings, data ); + } + + if ( redraw === undefined || redraw ) { + api.draw(); + } + + return data; + }; + + + /** + * Restore the table to it's original state in the DOM by removing all of DataTables + * enhancements, alterations to the DOM structure of the table and event listeners. + * @param {boolean} [remove=false] Completely remove the table from the DOM + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * // This example is fairly pointless in reality, but shows how fnDestroy can be used + * var oTable = $('#example').dataTable(); + * oTable.fnDestroy(); + * } ); + */ + this.fnDestroy = function ( remove ) + { + this.api( true ).destroy( remove ); + }; + + + /** + * Redraw the table + * @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw. + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Re-draw the table - you wouldn't want to do it here, but it's an example :-) + * oTable.fnDraw(); + * } ); + */ + this.fnDraw = function( complete ) + { + // Note that this isn't an exact match to the old call to _fnDraw - it takes + // into account the new data, but can hold position. + this.api( true ).draw( complete ); + }; + + + /** + * Filter the input based on data + * @param {string} sInput String to filter the table on + * @param {int|null} [iColumn] Column to limit filtering to + * @param {bool} [bRegex=false] Treat as regular expression or not + * @param {bool} [bSmart=true] Perform smart filtering or not + * @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es) + * @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false) + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Sometime later - filter... + * oTable.fnFilter( 'test string' ); + * } ); + */ + this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive ) + { + var api = this.api( true ); + + if ( iColumn === null || iColumn === undefined ) { + api.search( sInput, bRegex, bSmart, bCaseInsensitive ); + } + else { + api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive ); + } + + api.draw(); + }; + + + /** + * Get the data for the whole table, an individual row or an individual cell based on the + * provided parameters. + * @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as + * a TR node then the data source for the whole row will be returned. If given as a + * TD/TH cell node then iCol will be automatically calculated and the data for the + * cell returned. If given as an integer, then this is treated as the aoData internal + * data index for the row (see fnGetPosition) and the data for that row used. + * @param {int} [col] Optional column index that you want the data of. + * @returns {array|object|string} If mRow is undefined, then the data for all rows is + * returned. If mRow is defined, just data for that row, and is iCol is + * defined, only data for the designated cell is returned. + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * // Row data + * $(document).ready(function() { + * oTable = $('#example').dataTable(); + * + * oTable.$('tr').click( function () { + * var data = oTable.fnGetData( this ); + * // ... do something with the array / object of data for the row + * } ); + * } ); + * + * @example + * // Individual cell data + * $(document).ready(function() { + * oTable = $('#example').dataTable(); + * + * oTable.$('td').click( function () { + * var sData = oTable.fnGetData( this ); + * alert( 'The cell clicked on had the value of '+sData ); + * } ); + * } ); + */ + this.fnGetData = function( src, col ) + { + var api = this.api( true ); + + if ( src !== undefined ) { + var type = src.nodeName ? src.nodeName.toLowerCase() : ''; + + return col !== undefined || type == 'td' || type == 'th' ? + api.cell( src, col ).data() : + api.row( src ).data() || null; + } + + return api.data().toArray(); + }; + + + /** + * Get an array of the TR nodes that are used in the table's body. Note that you will + * typically want to use the '$' API method in preference to this as it is more + * flexible. + * @param {int} [iRow] Optional row index for the TR element you want + * @returns {array|node} If iRow is undefined, returns an array of all TR elements + * in the table's body, or iRow is defined, just the TR element requested. + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Get the nodes from the table + * var nNodes = oTable.fnGetNodes( ); + * } ); + */ + this.fnGetNodes = function( iRow ) + { + var api = this.api( true ); + + return iRow !== undefined ? + api.row( iRow ).node() : + api.rows().nodes().flatten().toArray(); + }; + + + /** + * Get the array indexes of a particular cell from it's DOM element + * and column index including hidden columns + * @param {node} node this can either be a TR, TD or TH in the table's body + * @returns {int} If nNode is given as a TR, then a single index is returned, or + * if given as a cell, an array of [row index, column index (visible), + * column index (all)] is given. + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * $('#example tbody td').click( function () { + * // Get the position of the current data from the node + * var aPos = oTable.fnGetPosition( this ); + * + * // Get the data array for this row + * var aData = oTable.fnGetData( aPos[0] ); + * + * // Update the data array and return the value + * aData[ aPos[1] ] = 'clicked'; + * this.innerHTML = 'clicked'; + * } ); + * + * // Init DataTables + * oTable = $('#example').dataTable(); + * } ); + */ + this.fnGetPosition = function( node ) + { + var api = this.api( true ); + var nodeName = node.nodeName.toUpperCase(); + + if ( nodeName == 'TR' ) { + return api.row( node ).index(); + } + else if ( nodeName == 'TD' || nodeName == 'TH' ) { + var cell = api.cell( node ).index(); + + return [ + cell.row, + cell.columnVisible, + cell.column + ]; + } + return null; + }; + + + /** + * Check to see if a row is 'open' or not. + * @param {node} nTr the table row to check + * @returns {boolean} true if the row is currently open, false otherwise + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable; + * + * // 'open' an information row when a row is clicked on + * $('#example tbody tr').click( function () { + * if ( oTable.fnIsOpen(this) ) { + * oTable.fnClose( this ); + * } else { + * oTable.fnOpen( this, "Temporary row opened", "info_row" ); + * } + * } ); + * + * oTable = $('#example').dataTable(); + * } ); + */ + this.fnIsOpen = function( nTr ) + { + return this.api( true ).row( nTr ).child.isShown(); + }; + + + /** + * This function will place a new row directly after a row which is currently + * on display on the page, with the HTML contents that is passed into the + * function. This can be used, for example, to ask for confirmation that a + * particular record should be deleted. + * @param {node} nTr The table row to 'open' + * @param {string|node|jQuery} mHtml The HTML to put into the row + * @param {string} sClass Class to give the new TD cell + * @returns {node} The row opened. Note that if the table row passed in as the + * first parameter, is not found in the table, this method will silently + * return. + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable; + * + * // 'open' an information row when a row is clicked on + * $('#example tbody tr').click( function () { + * if ( oTable.fnIsOpen(this) ) { + * oTable.fnClose( this ); + * } else { + * oTable.fnOpen( this, "Temporary row opened", "info_row" ); + * } + * } ); + * + * oTable = $('#example').dataTable(); + * } ); + */ + this.fnOpen = function( nTr, mHtml, sClass ) + { + return this.api( true ) + .row( nTr ) + .child( mHtml, sClass ) + .show() + .child()[0]; + }; + + + /** + * Change the pagination - provides the internal logic for pagination in a simple API + * function. With this function you can have a DataTables table go to the next, + * previous, first or last pages. + * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last" + * or page number to jump to (integer), note that page 0 is the first page. + * @param {bool} [bRedraw=true] Redraw the table or not + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * oTable.fnPageChange( 'next' ); + * } ); + */ + this.fnPageChange = function ( mAction, bRedraw ) + { + var api = this.api( true ).page( mAction ); + + if ( bRedraw === undefined || bRedraw ) { + api.draw(false); + } + }; + + + /** + * Show a particular column + * @param {int} iCol The column whose display should be changed + * @param {bool} bShow Show (true) or hide (false) the column + * @param {bool} [bRedraw=true] Redraw the table or not + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Hide the second column after initialisation + * oTable.fnSetColumnVis( 1, false ); + * } ); + */ + this.fnSetColumnVis = function ( iCol, bShow, bRedraw ) + { + var api = this.api( true ).column( iCol ).visible( bShow ); + + if ( bRedraw === undefined || bRedraw ) { + api.columns.adjust().draw(); + } + }; + + + /** + * Get the settings for a particular table for external manipulation + * @returns {object} DataTables settings object. See + * {@link DataTable.models.oSettings} + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * var oSettings = oTable.fnSettings(); + * + * // Show an example parameter from the settings + * alert( oSettings._iDisplayStart ); + * } ); + */ + this.fnSettings = function() + { + return _fnSettingsFromNode( this[_ext.iApiIndex] ); + }; + + + /** + * Sort the table by a particular column + * @param {int} iCol the data index to sort on. Note that this will not match the + * 'display index' if you have hidden data entries + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Sort immediately with columns 0 and 1 + * oTable.fnSort( [ [0,'asc'], [1,'asc'] ] ); + * } ); + */ + this.fnSort = function( aaSort ) + { + this.api( true ).order( aaSort ).draw(); + }; + + + /** + * Attach a sort listener to an element for a given column + * @param {node} nNode the element to attach the sort listener to + * @param {int} iColumn the column that a click on this node will sort on + * @param {function} [fnCallback] callback function when sort is run + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Sort on column 1, when 'sorter' is clicked on + * oTable.fnSortListener( document.getElementById('sorter'), 1 ); + * } ); + */ + this.fnSortListener = function( nNode, iColumn, fnCallback ) + { + this.api( true ).order.listener( nNode, iColumn, fnCallback ); + }; + + + /** + * Update a table cell or row - this method will accept either a single value to + * update the cell with, an array of values with one element for each column or + * an object in the same format as the original data source. The function is + * self-referencing in order to make the multi column updates easier. + * @param {object|array|string} mData Data to update the cell/row with + * @param {node|int} mRow TR element you want to update or the aoData index + * @param {int} [iColumn] The column to update, give as null or undefined to + * update a whole row. + * @param {bool} [bRedraw=true] Redraw the table or not + * @param {bool} [bAction=true] Perform pre-draw actions or not + * @returns {int} 0 on success, 1 on error + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell + * oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row + * } ); + */ + this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction ) + { + var api = this.api( true ); + + if ( iColumn === undefined || iColumn === null ) { + api.row( mRow ).data( mData ); + } + else { + api.cell( mRow, iColumn ).data( mData ); + } + + if ( bAction === undefined || bAction ) { + api.columns.adjust(); + } + + if ( bRedraw === undefined || bRedraw ) { + api.draw(); + } + return 0; + }; + + + /** + * Provide a common method for plug-ins to check the version of DataTables being used, in order + * to ensure compatibility. + * @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the + * formats "X" and "X.Y" are also acceptable. + * @returns {boolean} true if this version of DataTables is greater or equal to the required + * version, or false if this version of DataTales is not suitable + * @method + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * alert( oTable.fnVersionCheck( '1.9.0' ) ); + * } ); + */ + this.fnVersionCheck = _ext.fnVersionCheck; + + + var _that = this; + var emptyInit = options === undefined; + var len = this.length; + + if ( emptyInit ) { + options = {}; + } + + this.oApi = this.internal = _ext.internal; + + // Extend with old style plug-in API methods + for ( var fn in DataTable.ext.internal ) { + if ( fn ) { + this[fn] = _fnExternApiFunc(fn); + } + } + + this.each(function() { + // For each initialisation we want to give it a clean initialisation + // object that can be bashed around + var o = {}; + var oInit = len > 1 ? // optimisation for single table case + _fnExtend( o, options, true ) : + options; + + /*global oInit,_that,emptyInit*/ + var i=0, iLen, j, jLen, k, kLen; + var sId = this.getAttribute( 'id' ); + var bInitHandedOff = false; + var defaults = DataTable.defaults; + var $this = $(this); + + + /* Sanity check */ + if ( this.nodeName.toLowerCase() != 'table' ) + { + _fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 ); + return; + } + + /* Backwards compatibility for the defaults */ + _fnCompatOpts( defaults ); + _fnCompatCols( defaults.column ); + + /* Convert the camel-case defaults to Hungarian */ + _fnCamelToHungarian( defaults, defaults, true ); + _fnCamelToHungarian( defaults.column, defaults.column, true ); + + /* Setting up the initialisation object */ + _fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ) ); + + + + /* Check to see if we are re-initialising a table */ + var allSettings = DataTable.settings; + for ( i=0, iLen=allSettings.length ; i').appendTo(this); + } + oSettings.nTHead = thead[0]; + + var tbody = $this.children('tbody'); + if ( tbody.length === 0 ) + { + tbody = $('
` node is a DataTable table already or not. + * + * @param {node|jquery|string} table Table node, jQuery object or jQuery + * selector for the table to test. Note that if more than more than one + * table is passed on, only the first will be checked + * @returns {boolean} true the table given is a DataTable, or false otherwise + * @static + * @dtopt API-Static + * + * @example + * if ( ! $.fn.DataTable.isDataTable( '#example' ) ) { + * $('#example').dataTable(); + * } + */ + DataTable.isDataTable = DataTable.fnIsDataTable = function ( table ) + { + var t = $(table).get(0); + var is = false; + + $.each( DataTable.settings, function (i, o) { + var head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null; + var foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null; + + if ( o.nTable === t || head === t || foot === t ) { + is = true; + } + } ); + + return is; + }; + + + /** + * Get all DataTable tables that have been initialised - optionally you can + * select to get only currently visible tables. + * + * @param {boolean} [visible=false] Flag to indicate if you want all (default) + * or visible tables only. + * @returns {array} Array of `table` nodes (not DataTable instances) which are + * DataTables + * @static + * @dtopt API-Static + * + * @example + * $.each( $.fn.dataTable.tables(true), function () { + * $(table).DataTable().columns.adjust(); + * } ); + */ + DataTable.tables = DataTable.fnTables = function ( visible ) + { + var api = false; + + if ( $.isPlainObject( visible ) ) { + api = visible.api; + visible = visible.visible; + } + + var a = $.map( DataTable.settings, function (o) { + if ( !visible || (visible && $(o.nTable).is(':visible')) ) { + return o.nTable; + } + } ); + + return api ? + new _Api( a ) : + a; + }; + + + /** + * DataTables utility methods + * + * This namespace provides helper methods that DataTables uses internally to + * create a DataTable, but which are not exclusively used only for DataTables. + * These methods can be used by extension authors to save the duplication of + * code. + * + * @namespace + */ + DataTable.util = { + /** + * Throttle the calls to a function. Arguments and context are maintained + * for the throttled function. + * + * @param {function} fn Function to be called + * @param {integer} freq Call frequency in mS + * @return {function} Wrapped function + */ + throttle: _fnThrottle, + + + /** + * Escape a string such that it can be used in a regular expression + * + * @param {string} sVal string to escape + * @returns {string} escaped string + */ + escapeRegex: _fnEscapeRegex + }; + + + /** + * Convert from camel case parameters to Hungarian notation. This is made public + * for the extensions to provide the same ability as DataTables core to accept + * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase + * parameters. + * + * @param {object} src The model object which holds all parameters that can be + * mapped. + * @param {object} user The object to convert from camel case to Hungarian. + * @param {boolean} force When set to `true`, properties which already have a + * Hungarian value in the `user` object will be overwritten. Otherwise they + * won't be. + */ + DataTable.camelToHungarian = _fnCamelToHungarian; + + + + /** + * + */ + _api_register( '$()', function ( selector, opts ) { + var + rows = this.rows( opts ).nodes(), // Get all rows + jqRows = $(rows); + + return $( [].concat( + jqRows.filter( selector ).toArray(), + jqRows.find( selector ).toArray() + ) ); + } ); + + + // jQuery functions to operate on the tables + $.each( [ 'on', 'one', 'off' ], function (i, key) { + _api_register( key+'()', function ( /* event, handler */ ) { + var args = Array.prototype.slice.call(arguments); + + // Add the `dt` namespace automatically if it isn't already present + if ( ! args[0].match(/\.dt\b/) ) { + args[0] += '.dt'; + } + + var inst = $( this.tables().nodes() ); + inst[key].apply( inst, args ); + return this; + } ); + } ); + + + _api_register( 'clear()', function () { + return this.iterator( 'table', function ( settings ) { + _fnClearTable( settings ); + } ); + } ); + + + _api_register( 'settings()', function () { + return new _Api( this.context, this.context ); + } ); + + + _api_register( 'init()', function () { + var ctx = this.context; + return ctx.length ? ctx[0].oInit : null; + } ); + + + _api_register( 'data()', function () { + return this.iterator( 'table', function ( settings ) { + return _pluck( settings.aoData, '_aData' ); + } ).flatten(); + } ); + + + _api_register( 'destroy()', function ( remove ) { + remove = remove || false; + + return this.iterator( 'table', function ( settings ) { + var orig = settings.nTableWrapper.parentNode; + var classes = settings.oClasses; + var table = settings.nTable; + var tbody = settings.nTBody; + var thead = settings.nTHead; + var tfoot = settings.nTFoot; + var jqTable = $(table); + var jqTbody = $(tbody); + var jqWrapper = $(settings.nTableWrapper); + var rows = $.map( settings.aoData, function (r) { return r.nTr; } ); + var i, ien; + + // Flag to note that the table is currently being destroyed - no action + // should be taken + settings.bDestroying = true; + + // Fire off the destroy callbacks for plug-ins etc + _fnCallbackFire( settings, "aoDestroyCallback", "destroy", [settings] ); + + // If not being removed from the document, make all columns visible + if ( ! remove ) { + new _Api( settings ).columns().visible( true ); + } + + // Blitz all `DT` namespaced events (these are internal events, the + // lowercase, `dt` events are user subscribed and they are responsible + // for removing them + jqWrapper.unbind('.DT').find(':not(tbody *)').unbind('.DT'); + $(window).unbind('.DT-'+settings.sInstance); + + // When scrolling we had to break the table up - restore it + if ( table != thead.parentNode ) { + jqTable.children('thead').detach(); + jqTable.append( thead ); + } + + if ( tfoot && table != tfoot.parentNode ) { + jqTable.children('tfoot').detach(); + jqTable.append( tfoot ); + } + + settings.aaSorting = []; + settings.aaSortingFixed = []; + _fnSortingClasses( settings ); + + $( rows ).removeClass( settings.asStripeClasses.join(' ') ); + + $('th, td', thead).removeClass( classes.sSortable+' '+ + classes.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone + ); + + if ( settings.bJUI ) { + $('th span.'+classes.sSortIcon+ ', td span.'+classes.sSortIcon, thead).detach(); + $('th, td', thead).each( function () { + var wrapper = $('div.'+classes.sSortJUIWrapper, this); + $(this).append( wrapper.contents() ); + wrapper.detach(); + } ); + } + + // Add the TR elements back into the table in their original order + jqTbody.children().detach(); + jqTbody.append( rows ); + + // Remove the DataTables generated nodes, events and classes + var removedMethod = remove ? 'remove' : 'detach'; + jqTable[ removedMethod ](); + jqWrapper[ removedMethod ](); + + // If we need to reattach the table to the document + if ( ! remove && orig ) { + // insertBefore acts like appendChild if !arg[1] + orig.insertBefore( table, settings.nTableReinsertBefore ); + + // Restore the width of the original table - was read from the style property, + // so we can restore directly to that + jqTable + .css( 'width', settings.sDestroyWidth ) + .removeClass( classes.sTable ); + + // If the were originally stripe classes - then we add them back here. + // Note this is not fool proof (for example if not all rows had stripe + // classes - but it's a good effort without getting carried away + ien = settings.asDestroyStripes.length; + + if ( ien ) { + jqTbody.children().each( function (i) { + $(this).addClass( settings.asDestroyStripes[i % ien] ); + } ); + } + } + + /* Remove the settings object from the settings array */ + var idx = $.inArray( settings, DataTable.settings ); + if ( idx !== -1 ) { + DataTable.settings.splice( idx, 1 ); + } + } ); + } ); + + + // Add the `every()` method for rows, columns and cells in a compact form + $.each( [ 'column', 'row', 'cell' ], function ( i, type ) { + _api_register( type+'s().every()', function ( fn ) { + var opts = this.selector.opts; + var api = this; + + return this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) { + // Rows and columns: + // arg1 - index + // arg2 - table counter + // arg3 - loop counter + // arg4 - undefined + // Cells: + // arg1 - row index + // arg2 - column index + // arg3 - table counter + // arg4 - loop counter + fn.call( + api[ type ]( + arg1, + type==='cell' ? arg2 : opts, + type==='cell' ? opts : undefined + ), + arg1, arg2, arg3, arg4 + ); + } ); + } ); + } ); + + + // i18n method for extensions to be able to use the language object from the + // DataTable + _api_register( 'i18n()', function ( token, def, plural ) { + var ctx = this.context[0]; + var resolved = _fnGetObjectDataFn( token )( ctx.oLanguage ); + + if ( resolved === undefined ) { + resolved = def; + } + + if ( plural !== undefined && $.isPlainObject( resolved ) ) { + resolved = resolved[ plural ] !== undefined ? + resolved[ plural ] : + resolved._; + } + + return resolved.replace( '%d', plural ); // nb: plural might be undefined, + } ); + + /** + * Version string for plug-ins to check compatibility. Allowed format is + * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used + * only for non-release builds. See http://semver.org/ for more information. + * @member + * @type string + * @default Version number + */ + DataTable.version = "1.10.11"; + + /** + * Private data store, containing all of the settings objects that are + * created for the tables on a given page. + * + * Note that the `DataTable.settings` object is aliased to + * `jQuery.fn.dataTableExt` through which it may be accessed and + * manipulated, or `jQuery.fn.dataTable.settings`. + * @member + * @type array + * @default [] + * @private + */ + DataTable.settings = []; + + /** + * Object models container, for the various models that DataTables has + * available to it. These models define the objects that are used to hold + * the active state and configuration of the table. + * @namespace + */ + DataTable.models = {}; + + + + /** + * Template object for the way in which DataTables holds information about + * search information for the global filter and individual column filters. + * @namespace + */ + DataTable.models.oSearch = { + /** + * Flag to indicate if the filtering should be case insensitive or not + * @type boolean + * @default true + */ + "bCaseInsensitive": true, + + /** + * Applied search term + * @type string + * @default Empty string + */ + "sSearch": "", + + /** + * Flag to indicate if the search term should be interpreted as a + * regular expression (true) or not (false) and therefore and special + * regex characters escaped. + * @type boolean + * @default false + */ + "bRegex": false, + + /** + * Flag to indicate if DataTables is to use its smart filtering or not. + * @type boolean + * @default true + */ + "bSmart": true + }; + + + + + /** + * Template object for the way in which DataTables holds information about + * each individual row. This is the object format used for the settings + * aoData array. + * @namespace + */ + DataTable.models.oRow = { + /** + * TR element for the row + * @type node + * @default null + */ + "nTr": null, + + /** + * Array of TD elements for each row. This is null until the row has been + * created. + * @type array nodes + * @default [] + */ + "anCells": null, + + /** + * Data object from the original data source for the row. This is either + * an array if using the traditional form of DataTables, or an object if + * using mData options. The exact type will depend on the passed in + * data from the data source, or will be an array if using DOM a data + * source. + * @type array|object + * @default [] + */ + "_aData": [], + + /** + * Sorting data cache - this array is ostensibly the same length as the + * number of columns (although each index is generated only as it is + * needed), and holds the data that is used for sorting each column in the + * row. We do this cache generation at the start of the sort in order that + * the formatting of the sort data need be done only once for each cell + * per sort. This array should not be read from or written to by anything + * other than the master sorting methods. + * @type array + * @default null + * @private + */ + "_aSortData": null, + + /** + * Per cell filtering data cache. As per the sort data cache, used to + * increase the performance of the filtering in DataTables + * @type array + * @default null + * @private + */ + "_aFilterData": null, + + /** + * Filtering data cache. This is the same as the cell filtering cache, but + * in this case a string rather than an array. This is easily computed with + * a join on `_aFilterData`, but is provided as a cache so the join isn't + * needed on every search (memory traded for performance) + * @type array + * @default null + * @private + */ + "_sFilterRow": null, + + /** + * Cache of the class name that DataTables has applied to the row, so we + * can quickly look at this variable rather than needing to do a DOM check + * on className for the nTr property. + * @type string + * @default Empty string + * @private + */ + "_sRowStripe": "", + + /** + * Denote if the original data source was from the DOM, or the data source + * object. This is used for invalidating data, so DataTables can + * automatically read data from the original source, unless uninstructed + * otherwise. + * @type string + * @default null + * @private + */ + "src": null, + + /** + * Index in the aoData array. This saves an indexOf lookup when we have the + * object, but want to know the index + * @type integer + * @default -1 + * @private + */ + "idx": -1 + }; + + + /** + * Template object for the column information object in DataTables. This object + * is held in the settings aoColumns array and contains all the information that + * DataTables needs about each individual column. + * + * Note that this object is related to {@link DataTable.defaults.column} + * but this one is the internal data store for DataTables's cache of columns. + * It should NOT be manipulated outside of DataTables. Any configuration should + * be done through the initialisation options. + * @namespace + */ + DataTable.models.oColumn = { + /** + * Column index. This could be worked out on-the-fly with $.inArray, but it + * is faster to just hold it as a variable + * @type integer + * @default null + */ + "idx": null, + + /** + * A list of the columns that sorting should occur on when this column + * is sorted. That this property is an array allows multi-column sorting + * to be defined for a column (for example first name / last name columns + * would benefit from this). The values are integers pointing to the + * columns to be sorted on (typically it will be a single integer pointing + * at itself, but that doesn't need to be the case). + * @type array + */ + "aDataSort": null, + + /** + * Define the sorting directions that are applied to the column, in sequence + * as the column is repeatedly sorted upon - i.e. the first value is used + * as the sorting direction when the column if first sorted (clicked on). + * Sort it again (click again) and it will move on to the next index. + * Repeat until loop. + * @type array + */ + "asSorting": null, + + /** + * Flag to indicate if the column is searchable, and thus should be included + * in the filtering or not. + * @type boolean + */ + "bSearchable": null, + + /** + * Flag to indicate if the column is sortable or not. + * @type boolean + */ + "bSortable": null, + + /** + * Flag to indicate if the column is currently visible in the table or not + * @type boolean + */ + "bVisible": null, + + /** + * Store for manual type assignment using the `column.type` option. This + * is held in store so we can manipulate the column's `sType` property. + * @type string + * @default null + * @private + */ + "_sManualType": null, + + /** + * Flag to indicate if HTML5 data attributes should be used as the data + * source for filtering or sorting. True is either are. + * @type boolean + * @default false + * @private + */ + "_bAttrSrc": false, + + /** + * Developer definable function that is called whenever a cell is created (Ajax source, + * etc) or processed for input (DOM source). This can be used as a compliment to mRender + * allowing you to modify the DOM element (add background colour for example) when the + * element is available. + * @type function + * @param {element} nTd The TD node that has been created + * @param {*} sData The Data for the cell + * @param {array|object} oData The data for the whole row + * @param {int} iRow The row index for the aoData data store + * @default null + */ + "fnCreatedCell": null, + + /** + * Function to get data from a cell in a column. You should never + * access data directly through _aData internally in DataTables - always use + * the method attached to this property. It allows mData to function as + * required. This function is automatically assigned by the column + * initialisation method + * @type function + * @param {array|object} oData The data array/object for the array + * (i.e. aoData[]._aData) + * @param {string} sSpecific The specific data type you want to get - + * 'display', 'type' 'filter' 'sort' + * @returns {*} The data for the cell from the given row's data + * @default null + */ + "fnGetData": null, + + /** + * Function to set data for a cell in the column. You should never + * set the data directly to _aData internally in DataTables - always use + * this method. It allows mData to function as required. This function + * is automatically assigned by the column initialisation method + * @type function + * @param {array|object} oData The data array/object for the array + * (i.e. aoData[]._aData) + * @param {*} sValue Value to set + * @default null + */ + "fnSetData": null, + + /** + * Property to read the value for the cells in the column from the data + * source array / object. If null, then the default content is used, if a + * function is given then the return from the function is used. + * @type function|int|string|null + * @default null + */ + "mData": null, + + /** + * Partner property to mData which is used (only when defined) to get + * the data - i.e. it is basically the same as mData, but without the + * 'set' option, and also the data fed to it is the result from mData. + * This is the rendering method to match the data method of mData. + * @type function|int|string|null + * @default null + */ + "mRender": null, + + /** + * Unique header TH/TD element for this column - this is what the sorting + * listener is attached to (if sorting is enabled.) + * @type node + * @default null + */ + "nTh": null, + + /** + * Unique footer TH/TD element for this column (if there is one). Not used + * in DataTables as such, but can be used for plug-ins to reference the + * footer for each column. + * @type node + * @default null + */ + "nTf": null, + + /** + * The class to apply to all TD elements in the table's TBODY for the column + * @type string + * @default null + */ + "sClass": null, + + /** + * When DataTables calculates the column widths to assign to each column, + * it finds the longest string in each column and then constructs a + * temporary table and reads the widths from that. The problem with this + * is that "mmm" is much wider then "iiii", but the latter is a longer + * string - thus the calculation can go wrong (doing it properly and putting + * it into an DOM object and measuring that is horribly(!) slow). Thus as + * a "work around" we provide this option. It will append its value to the + * text that is found to be the longest string for the column - i.e. padding. + * @type string + */ + "sContentPadding": null, + + /** + * Allows a default value to be given for a column's data, and will be used + * whenever a null data source is encountered (this can be because mData + * is set to null, or because the data source itself is null). + * @type string + * @default null + */ + "sDefaultContent": null, + + /** + * Name for the column, allowing reference to the column by name as well as + * by index (needs a lookup to work by name). + * @type string + */ + "sName": null, + + /** + * Custom sorting data type - defines which of the available plug-ins in + * afnSortData the custom sorting will use - if any is defined. + * @type string + * @default std + */ + "sSortDataType": 'std', + + /** + * Class to be applied to the header element when sorting on this column + * @type string + * @default null + */ + "sSortingClass": null, + + /** + * Class to be applied to the header element when sorting on this column - + * when jQuery UI theming is used. + * @type string + * @default null + */ + "sSortingClassJUI": null, + + /** + * Title of the column - what is seen in the TH element (nTh). + * @type string + */ + "sTitle": null, + + /** + * Column sorting and filtering type + * @type string + * @default null + */ + "sType": null, + + /** + * Width of the column + * @type string + * @default null + */ + "sWidth": null, + + /** + * Width of the column when it was first "encountered" + * @type string + * @default null + */ + "sWidthOrig": null + }; + + + /* + * Developer note: The properties of the object below are given in Hungarian + * notation, that was used as the interface for DataTables prior to v1.10, however + * from v1.10 onwards the primary interface is camel case. In order to avoid + * breaking backwards compatibility utterly with this change, the Hungarian + * version is still, internally the primary interface, but is is not documented + * - hence the @name tags in each doc comment. This allows a Javascript function + * to create a map from Hungarian notation to camel case (going the other direction + * would require each property to be listed, which would at around 3K to the size + * of DataTables, while this method is about a 0.5K hit. + * + * Ultimately this does pave the way for Hungarian notation to be dropped + * completely, but that is a massive amount of work and will break current + * installs (therefore is on-hold until v2). + */ + + /** + * Initialisation options that can be given to DataTables at initialisation + * time. + * @namespace + */ + DataTable.defaults = { + /** + * An array of data to use for the table, passed in at initialisation which + * will be used in preference to any data which is already in the DOM. This is + * particularly useful for constructing tables purely in Javascript, for + * example with a custom Ajax call. + * @type array + * @default null + * + * @dtopt Option + * @name DataTable.defaults.data + * + * @example + * // Using a 2D array data source + * $(document).ready( function () { + * $('#example').dataTable( { + * "data": [ + * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'], + * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'], + * ], + * "columns": [ + * { "title": "Engine" }, + * { "title": "Browser" }, + * { "title": "Platform" }, + * { "title": "Version" }, + * { "title": "Grade" } + * ] + * } ); + * } ); + * + * @example + * // Using an array of objects as a data source (`data`) + * $(document).ready( function () { + * $('#example').dataTable( { + * "data": [ + * { + * "engine": "Trident", + * "browser": "Internet Explorer 4.0", + * "platform": "Win 95+", + * "version": 4, + * "grade": "X" + * }, + * { + * "engine": "Trident", + * "browser": "Internet Explorer 5.0", + * "platform": "Win 95+", + * "version": 5, + * "grade": "C" + * } + * ], + * "columns": [ + * { "title": "Engine", "data": "engine" }, + * { "title": "Browser", "data": "browser" }, + * { "title": "Platform", "data": "platform" }, + * { "title": "Version", "data": "version" }, + * { "title": "Grade", "data": "grade" } + * ] + * } ); + * } ); + */ + "aaData": null, + + + /** + * If ordering is enabled, then DataTables will perform a first pass sort on + * initialisation. You can define which column(s) the sort is performed + * upon, and the sorting direction, with this variable. The `sorting` array + * should contain an array for each column to be sorted initially containing + * the column's index and a direction string ('asc' or 'desc'). + * @type array + * @default [[0,'asc']] + * + * @dtopt Option + * @name DataTable.defaults.order + * + * @example + * // Sort by 3rd column first, and then 4th column + * $(document).ready( function() { + * $('#example').dataTable( { + * "order": [[2,'asc'], [3,'desc']] + * } ); + * } ); + * + * // No initial sorting + * $(document).ready( function() { + * $('#example').dataTable( { + * "order": [] + * } ); + * } ); + */ + "aaSorting": [[0,'asc']], + + + /** + * This parameter is basically identical to the `sorting` parameter, but + * cannot be overridden by user interaction with the table. What this means + * is that you could have a column (visible or hidden) which the sorting + * will always be forced on first - any sorting after that (from the user) + * will then be performed as required. This can be useful for grouping rows + * together. + * @type array + * @default null + * + * @dtopt Option + * @name DataTable.defaults.orderFixed + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "orderFixed": [[0,'asc']] + * } ); + * } ) + */ + "aaSortingFixed": [], + + + /** + * DataTables can be instructed to load data to display in the table from a + * Ajax source. This option defines how that Ajax call is made and where to. + * + * The `ajax` property has three different modes of operation, depending on + * how it is defined. These are: + * + * * `string` - Set the URL from where the data should be loaded from. + * * `object` - Define properties for `jQuery.ajax`. + * * `function` - Custom data get function + * + * `string` + * -------- + * + * As a string, the `ajax` property simply defines the URL from which + * DataTables will load data. + * + * `object` + * -------- + * + * As an object, the parameters in the object are passed to + * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control + * of the Ajax request. DataTables has a number of default parameters which + * you can override using this option. Please refer to the jQuery + * documentation for a full description of the options available, although + * the following parameters provide additional options in DataTables or + * require special consideration: + * + * * `data` - As with jQuery, `data` can be provided as an object, but it + * can also be used as a function to manipulate the data DataTables sends + * to the server. The function takes a single parameter, an object of + * parameters with the values that DataTables has readied for sending. An + * object may be returned which will be merged into the DataTables + * defaults, or you can add the items to the object that was passed in and + * not return anything from the function. This supersedes `fnServerParams` + * from DataTables 1.9-. + * + * * `dataSrc` - By default DataTables will look for the property `data` (or + * `aaData` for compatibility with DataTables 1.9-) when obtaining data + * from an Ajax source or for server-side processing - this parameter + * allows that property to be changed. You can use Javascript dotted + * object notation to get a data source for multiple levels of nesting, or + * it my be used as a function. As a function it takes a single parameter, + * the JSON returned from the server, which can be manipulated as + * required, with the returned value being that used by DataTables as the + * data source for the table. This supersedes `sAjaxDataProp` from + * DataTables 1.9-. + * + * * `success` - Should not be overridden it is used internally in + * DataTables. To manipulate / transform the data returned by the server + * use `ajax.dataSrc`, or use `ajax` as a function (see below). + * + * `function` + * ---------- + * + * As a function, making the Ajax call is left up to yourself allowing + * complete control of the Ajax request. Indeed, if desired, a method other + * than Ajax could be used to obtain the required data, such as Web storage + * or an AIR database. + * + * The function is given four parameters and no return is required. The + * parameters are: + * + * 1. _object_ - Data to send to the server + * 2. _function_ - Callback function that must be executed when the required + * data has been obtained. That data should be passed into the callback + * as the only parameter + * 3. _object_ - DataTables settings object for the table + * + * Note that this supersedes `fnServerData` from DataTables 1.9-. + * + * @type string|object|function + * @default null + * + * @dtopt Option + * @name DataTable.defaults.ajax + * @since 1.10.0 + * + * @example + * // Get JSON data from a file via Ajax. + * // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default). + * $('#example').dataTable( { + * "ajax": "data.json" + * } ); + * + * @example + * // Get JSON data from a file via Ajax, using `dataSrc` to change + * // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`) + * $('#example').dataTable( { + * "ajax": { + * "url": "data.json", + * "dataSrc": "tableData" + * } + * } ); + * + * @example + * // Get JSON data from a file via Ajax, using `dataSrc` to read data + * // from a plain array rather than an array in an object + * $('#example').dataTable( { + * "ajax": { + * "url": "data.json", + * "dataSrc": "" + * } + * } ); + * + * @example + * // Manipulate the data returned from the server - add a link to data + * // (note this can, should, be done using `render` for the column - this + * // is just a simple example of how the data can be manipulated). + * $('#example').dataTable( { + * "ajax": { + * "url": "data.json", + * "dataSrc": function ( json ) { + * for ( var i=0, ien=json.length ; iView message'; + * } + * return json; + * } + * } + * } ); + * + * @example + * // Add data to the request + * $('#example').dataTable( { + * "ajax": { + * "url": "data.json", + * "data": function ( d ) { + * return { + * "extra_search": $('#extra').val() + * }; + * } + * } + * } ); + * + * @example + * // Send request as POST + * $('#example').dataTable( { + * "ajax": { + * "url": "data.json", + * "type": "POST" + * } + * } ); + * + * @example + * // Get the data from localStorage (could interface with a form for + * // adding, editing and removing rows). + * $('#example').dataTable( { + * "ajax": function (data, callback, settings) { + * callback( + * JSON.parse( localStorage.getItem('dataTablesData') ) + * ); + * } + * } ); + */ + "ajax": null, + + + /** + * This parameter allows you to readily specify the entries in the length drop + * down menu that DataTables shows when pagination is enabled. It can be + * either a 1D array of options which will be used for both the displayed + * option and the value, or a 2D array which will use the array in the first + * position as the value, and the array in the second position as the + * displayed options (useful for language strings such as 'All'). + * + * Note that the `pageLength` property will be automatically set to the + * first value given in this array, unless `pageLength` is also provided. + * @type array + * @default [ 10, 25, 50, 100 ] + * + * @dtopt Option + * @name DataTable.defaults.lengthMenu + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]] + * } ); + * } ); + */ + "aLengthMenu": [ 10, 25, 50, 100 ], + + + /** + * The `columns` option in the initialisation parameter allows you to define + * details about the way individual columns behave. For a full list of + * column options that can be set, please see + * {@link DataTable.defaults.column}. Note that if you use `columns` to + * define your columns, you must have an entry in the array for every single + * column that you have in your table (these can be null if you don't which + * to specify any options). + * @member + * + * @name DataTable.defaults.column + */ + "aoColumns": null, + + /** + * Very similar to `columns`, `columnDefs` allows you to target a specific + * column, multiple columns, or all columns, using the `targets` property of + * each object in the array. This allows great flexibility when creating + * tables, as the `columnDefs` arrays can be of any length, targeting the + * columns you specifically want. `columnDefs` may use any of the column + * options available: {@link DataTable.defaults.column}, but it _must_ + * have `targets` defined in each object in the array. Values in the `targets` + * array may be: + *
    + *
  • a string - class name will be matched on the TH for the column
  • + *
  • 0 or a positive integer - column index counting from the left
  • + *
  • a negative integer - column index counting from the right
  • + *
  • the string "_all" - all columns (i.e. assign a default)
  • + *
+ * @member + * + * @name DataTable.defaults.columnDefs + */ + "aoColumnDefs": null, + + + /** + * Basically the same as `search`, this parameter defines the individual column + * filtering state at initialisation time. The array must be of the same size + * as the number of columns, and each element be an object with the parameters + * `search` and `escapeRegex` (the latter is optional). 'null' is also + * accepted and the default will be used. + * @type array + * @default [] + * + * @dtopt Option + * @name DataTable.defaults.searchCols + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "searchCols": [ + * null, + * { "search": "My filter" }, + * null, + * { "search": "^[0-9]", "escapeRegex": false } + * ] + * } ); + * } ) + */ + "aoSearchCols": [], + + + /** + * An array of CSS classes that should be applied to displayed rows. This + * array may be of any length, and DataTables will apply each class + * sequentially, looping when required. + * @type array + * @default null Will take the values determined by the `oClasses.stripe*` + * options + * + * @dtopt Option + * @name DataTable.defaults.stripeClasses + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "stripeClasses": [ 'strip1', 'strip2', 'strip3' ] + * } ); + * } ) + */ + "asStripeClasses": null, + + + /** + * Enable or disable automatic column width calculation. This can be disabled + * as an optimisation (it takes some time to calculate the widths) if the + * tables widths are passed in using `columns`. + * @type boolean + * @default true + * + * @dtopt Features + * @name DataTable.defaults.autoWidth + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "autoWidth": false + * } ); + * } ); + */ + "bAutoWidth": true, + + + /** + * Deferred rendering can provide DataTables with a huge speed boost when you + * are using an Ajax or JS data source for the table. This option, when set to + * true, will cause DataTables to defer the creation of the table elements for + * each row until they are needed for a draw - saving a significant amount of + * time. + * @type boolean + * @default false + * + * @dtopt Features + * @name DataTable.defaults.deferRender + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "ajax": "sources/arrays.txt", + * "deferRender": true + * } ); + * } ); + */ + "bDeferRender": false, + + + /** + * Replace a DataTable which matches the given selector and replace it with + * one which has the properties of the new initialisation object passed. If no + * table matches the selector, then the new DataTable will be constructed as + * per normal. + * @type boolean + * @default false + * + * @dtopt Options + * @name DataTable.defaults.destroy + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "srollY": "200px", + * "paginate": false + * } ); + * + * // Some time later.... + * $('#example').dataTable( { + * "filter": false, + * "destroy": true + * } ); + * } ); + */ + "bDestroy": false, + + + /** + * Enable or disable filtering of data. Filtering in DataTables is "smart" in + * that it allows the end user to input multiple words (space separated) and + * will match a row containing those words, even if not in the order that was + * specified (this allow matching across multiple columns). Note that if you + * wish to use filtering in DataTables this must remain 'true' - to remove the + * default filtering input box and retain filtering abilities, please use + * {@link DataTable.defaults.dom}. + * @type boolean + * @default true + * + * @dtopt Features + * @name DataTable.defaults.searching + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "searching": false + * } ); + * } ); + */ + "bFilter": true, + + + /** + * Enable or disable the table information display. This shows information + * about the data that is currently visible on the page, including information + * about filtered data if that action is being performed. + * @type boolean + * @default true + * + * @dtopt Features + * @name DataTable.defaults.info + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "info": false + * } ); + * } ); + */ + "bInfo": true, + + + /** + * Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some + * slightly different and additional mark-up from what DataTables has + * traditionally used). + * @type boolean + * @default false + * + * @dtopt Features + * @name DataTable.defaults.jQueryUI + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "jQueryUI": true + * } ); + * } ); + */ + "bJQueryUI": false, + + + /** + * Allows the end user to select the size of a formatted page from a select + * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`). + * @type boolean + * @default true + * + * @dtopt Features + * @name DataTable.defaults.lengthChange + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "lengthChange": false + * } ); + * } ); + */ + "bLengthChange": true, + + + /** + * Enable or disable pagination. + * @type boolean + * @default true + * + * @dtopt Features + * @name DataTable.defaults.paging + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "paging": false + * } ); + * } ); + */ + "bPaginate": true, + + + /** + * Enable or disable the display of a 'processing' indicator when the table is + * being processed (e.g. a sort). This is particularly useful for tables with + * large amounts of data where it can take a noticeable amount of time to sort + * the entries. + * @type boolean + * @default false + * + * @dtopt Features + * @name DataTable.defaults.processing + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "processing": true + * } ); + * } ); + */ + "bProcessing": false, + + + /** + * Retrieve the DataTables object for the given selector. Note that if the + * table has already been initialised, this parameter will cause DataTables + * to simply return the object that has already been set up - it will not take + * account of any changes you might have made to the initialisation object + * passed to DataTables (setting this parameter to true is an acknowledgement + * that you understand this). `destroy` can be used to reinitialise a table if + * you need. + * @type boolean + * @default false + * + * @dtopt Options + * @name DataTable.defaults.retrieve + * + * @example + * $(document).ready( function() { + * initTable(); + * tableActions(); + * } ); + * + * function initTable () + * { + * return $('#example').dataTable( { + * "scrollY": "200px", + * "paginate": false, + * "retrieve": true + * } ); + * } + * + * function tableActions () + * { + * var table = initTable(); + * // perform API operations with oTable + * } + */ + "bRetrieve": false, + + + /** + * When vertical (y) scrolling is enabled, DataTables will force the height of + * the table's viewport to the given height at all times (useful for layout). + * However, this can look odd when filtering data down to a small data set, + * and the footer is left "floating" further down. This parameter (when + * enabled) will cause DataTables to collapse the table's viewport down when + * the result set will fit within the given Y height. + * @type boolean + * @default false + * + * @dtopt Options + * @name DataTable.defaults.scrollCollapse + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "scrollY": "200", + * "scrollCollapse": true + * } ); + * } ); + */ + "bScrollCollapse": false, + + + /** + * Configure DataTables to use server-side processing. Note that the + * `ajax` parameter must also be given in order to give DataTables a + * source to obtain the required data for each draw. + * @type boolean + * @default false + * + * @dtopt Features + * @dtopt Server-side + * @name DataTable.defaults.serverSide + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "serverSide": true, + * "ajax": "xhr.php" + * } ); + * } ); + */ + "bServerSide": false, + + + /** + * Enable or disable sorting of columns. Sorting of individual columns can be + * disabled by the `sortable` option for each column. + * @type boolean + * @default true + * + * @dtopt Features + * @name DataTable.defaults.ordering + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "ordering": false + * } ); + * } ); + */ + "bSort": true, + + + /** + * Enable or display DataTables' ability to sort multiple columns at the + * same time (activated by shift-click by the user). + * @type boolean + * @default true + * + * @dtopt Options + * @name DataTable.defaults.orderMulti + * + * @example + * // Disable multiple column sorting ability + * $(document).ready( function () { + * $('#example').dataTable( { + * "orderMulti": false + * } ); + * } ); + */ + "bSortMulti": true, + + + /** + * Allows control over whether DataTables should use the top (true) unique + * cell that is found for a single column, or the bottom (false - default). + * This is useful when using complex headers. + * @type boolean + * @default false + * + * @dtopt Options + * @name DataTable.defaults.orderCellsTop + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "orderCellsTop": true + * } ); + * } ); + */ + "bSortCellsTop": false, + + + /** + * Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and + * `sorting\_3` to the columns which are currently being sorted on. This is + * presented as a feature switch as it can increase processing time (while + * classes are removed and added) so for large data sets you might want to + * turn this off. + * @type boolean + * @default true + * + * @dtopt Features + * @name DataTable.defaults.orderClasses + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "orderClasses": false + * } ); + * } ); + */ + "bSortClasses": true, + + + /** + * Enable or disable state saving. When enabled HTML5 `localStorage` will be + * used to save table display information such as pagination information, + * display length, filtering and sorting. As such when the end user reloads + * the page the display display will match what thy had previously set up. + * + * Due to the use of `localStorage` the default state saving is not supported + * in IE6 or 7. If state saving is required in those browsers, use + * `stateSaveCallback` to provide a storage solution such as cookies. + * @type boolean + * @default false + * + * @dtopt Features + * @name DataTable.defaults.stateSave + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "stateSave": true + * } ); + * } ); + */ + "bStateSave": false, + + + /** + * This function is called when a TR element is created (and all TD child + * elements have been inserted), or registered if using a DOM source, allowing + * manipulation of the TR element (adding classes etc). + * @type function + * @param {node} row "TR" element for the current row + * @param {array} data Raw data array for this row + * @param {int} dataIndex The index of this row in the internal aoData array + * + * @dtopt Callbacks + * @name DataTable.defaults.createdRow + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "createdRow": function( row, data, dataIndex ) { + * // Bold the grade for all 'A' grade browsers + * if ( data[4] == "A" ) + * { + * $('td:eq(4)', row).html( 'A' ); + * } + * } + * } ); + * } ); + */ + "fnCreatedRow": null, + + + /** + * This function is called on every 'draw' event, and allows you to + * dynamically modify any aspect you want about the created DOM. + * @type function + * @param {object} settings DataTables settings object + * + * @dtopt Callbacks + * @name DataTable.defaults.drawCallback + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "drawCallback": function( settings ) { + * alert( 'DataTables has redrawn the table' ); + * } + * } ); + * } ); + */ + "fnDrawCallback": null, + + + /** + * Identical to fnHeaderCallback() but for the table footer this function + * allows you to modify the table footer on every 'draw' event. + * @type function + * @param {node} foot "TR" element for the footer + * @param {array} data Full table data (as derived from the original HTML) + * @param {int} start Index for the current display starting point in the + * display array + * @param {int} end Index for the current display ending point in the + * display array + * @param {array int} display Index array to translate the visual position + * to the full data array + * + * @dtopt Callbacks + * @name DataTable.defaults.footerCallback + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "footerCallback": function( tfoot, data, start, end, display ) { + * tfoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+start; + * } + * } ); + * } ) + */ + "fnFooterCallback": null, + + + /** + * When rendering large numbers in the information element for the table + * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers + * to have a comma separator for the 'thousands' units (e.g. 1 million is + * rendered as "1,000,000") to help readability for the end user. This + * function will override the default method DataTables uses. + * @type function + * @member + * @param {int} toFormat number to be formatted + * @returns {string} formatted string for DataTables to show the number + * + * @dtopt Callbacks + * @name DataTable.defaults.formatNumber + * + * @example + * // Format a number using a single quote for the separator (note that + * // this can also be done with the language.thousands option) + * $(document).ready( function() { + * $('#example').dataTable( { + * "formatNumber": function ( toFormat ) { + * return toFormat.toString().replace( + * /\B(?=(\d{3})+(?!\d))/g, "'" + * ); + * }; + * } ); + * } ); + */ + "fnFormatNumber": function ( toFormat ) { + return toFormat.toString().replace( + /\B(?=(\d{3})+(?!\d))/g, + this.oLanguage.sThousands + ); + }, + + + /** + * This function is called on every 'draw' event, and allows you to + * dynamically modify the header row. This can be used to calculate and + * display useful information about the table. + * @type function + * @param {node} head "TR" element for the header + * @param {array} data Full table data (as derived from the original HTML) + * @param {int} start Index for the current display starting point in the + * display array + * @param {int} end Index for the current display ending point in the + * display array + * @param {array int} display Index array to translate the visual position + * to the full data array + * + * @dtopt Callbacks + * @name DataTable.defaults.headerCallback + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "fheaderCallback": function( head, data, start, end, display ) { + * head.getElementsByTagName('th')[0].innerHTML = "Displaying "+(end-start)+" records"; + * } + * } ); + * } ) + */ + "fnHeaderCallback": null, + + + /** + * The information element can be used to convey information about the current + * state of the table. Although the internationalisation options presented by + * DataTables are quite capable of dealing with most customisations, there may + * be times where you wish to customise the string further. This callback + * allows you to do exactly that. + * @type function + * @param {object} oSettings DataTables settings object + * @param {int} start Starting position in data for the draw + * @param {int} end End position in data for the draw + * @param {int} max Total number of rows in the table (regardless of + * filtering) + * @param {int} total Total number of rows in the data set, after filtering + * @param {string} pre The string that DataTables has formatted using it's + * own rules + * @returns {string} The string to be displayed in the information element. + * + * @dtopt Callbacks + * @name DataTable.defaults.infoCallback + * + * @example + * $('#example').dataTable( { + * "infoCallback": function( settings, start, end, max, total, pre ) { + * return start +" to "+ end; + * } + * } ); + */ + "fnInfoCallback": null, + + + /** + * Called when the table has been initialised. Normally DataTables will + * initialise sequentially and there will be no need for this function, + * however, this does not hold true when using external language information + * since that is obtained using an async XHR call. + * @type function + * @param {object} settings DataTables settings object + * @param {object} json The JSON object request from the server - only + * present if client-side Ajax sourced data is used + * + * @dtopt Callbacks + * @name DataTable.defaults.initComplete + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "initComplete": function(settings, json) { + * alert( 'DataTables has finished its initialisation.' ); + * } + * } ); + * } ) + */ + "fnInitComplete": null, + + + /** + * Called at the very start of each table draw and can be used to cancel the + * draw by returning false, any other return (including undefined) results in + * the full draw occurring). + * @type function + * @param {object} settings DataTables settings object + * @returns {boolean} False will cancel the draw, anything else (including no + * return) will allow it to complete. + * + * @dtopt Callbacks + * @name DataTable.defaults.preDrawCallback + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "preDrawCallback": function( settings ) { + * if ( $('#test').val() == 1 ) { + * return false; + * } + * } + * } ); + * } ); + */ + "fnPreDrawCallback": null, + + + /** + * This function allows you to 'post process' each row after it have been + * generated for each table draw, but before it is rendered on screen. This + * function might be used for setting the row class name etc. + * @type function + * @param {node} row "TR" element for the current row + * @param {array} data Raw data array for this row + * @param {int} displayIndex The display index for the current table draw + * @param {int} displayIndexFull The index of the data in the full list of + * rows (after filtering) + * + * @dtopt Callbacks + * @name DataTable.defaults.rowCallback + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "rowCallback": function( row, data, displayIndex, displayIndexFull ) { + * // Bold the grade for all 'A' grade browsers + * if ( data[4] == "A" ) { + * $('td:eq(4)', row).html( 'A' ); + * } + * } + * } ); + * } ); + */ + "fnRowCallback": null, + + + /** + * __Deprecated__ The functionality provided by this parameter has now been + * superseded by that provided through `ajax`, which should be used instead. + * + * This parameter allows you to override the default function which obtains + * the data from the server so something more suitable for your application. + * For example you could use POST data, or pull information from a Gears or + * AIR database. + * @type function + * @member + * @param {string} source HTTP source to obtain the data from (`ajax`) + * @param {array} data A key/value pair object containing the data to send + * to the server + * @param {function} callback to be called on completion of the data get + * process that will draw the data on the page. + * @param {object} settings DataTables settings object + * + * @dtopt Callbacks + * @dtopt Server-side + * @name DataTable.defaults.serverData + * + * @deprecated 1.10. Please use `ajax` for this functionality now. + */ + "fnServerData": null, + + + /** + * __Deprecated__ The functionality provided by this parameter has now been + * superseded by that provided through `ajax`, which should be used instead. + * + * It is often useful to send extra data to the server when making an Ajax + * request - for example custom filtering information, and this callback + * function makes it trivial to send extra information to the server. The + * passed in parameter is the data set that has been constructed by + * DataTables, and you can add to this or modify it as you require. + * @type function + * @param {array} data Data array (array of objects which are name/value + * pairs) that has been constructed by DataTables and will be sent to the + * server. In the case of Ajax sourced data with server-side processing + * this will be an empty array, for server-side processing there will be a + * significant number of parameters! + * @returns {undefined} Ensure that you modify the data array passed in, + * as this is passed by reference. + * + * @dtopt Callbacks + * @dtopt Server-side + * @name DataTable.defaults.serverParams + * + * @deprecated 1.10. Please use `ajax` for this functionality now. + */ + "fnServerParams": null, + + + /** + * Load the table state. With this function you can define from where, and how, the + * state of a table is loaded. By default DataTables will load from `localStorage` + * but you might wish to use a server-side database or cookies. + * @type function + * @member + * @param {object} settings DataTables settings object + * @return {object} The DataTables state object to be loaded + * + * @dtopt Callbacks + * @name DataTable.defaults.stateLoadCallback + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "stateSave": true, + * "stateLoadCallback": function (settings) { + * var o; + * + * // Send an Ajax request to the server to get the data. Note that + * // this is a synchronous request. + * $.ajax( { + * "url": "/state_load", + * "async": false, + * "dataType": "json", + * "success": function (json) { + * o = json; + * } + * } ); + * + * return o; + * } + * } ); + * } ); + */ + "fnStateLoadCallback": function ( settings ) { + try { + return JSON.parse( + (settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem( + 'DataTables_'+settings.sInstance+'_'+location.pathname + ) + ); + } catch (e) {} + }, + + + /** + * Callback which allows modification of the saved state prior to loading that state. + * This callback is called when the table is loading state from the stored data, but + * prior to the settings object being modified by the saved state. Note that for + * plug-in authors, you should use the `stateLoadParams` event to load parameters for + * a plug-in. + * @type function + * @param {object} settings DataTables settings object + * @param {object} data The state object that is to be loaded + * + * @dtopt Callbacks + * @name DataTable.defaults.stateLoadParams + * + * @example + * // Remove a saved filter, so filtering is never loaded + * $(document).ready( function() { + * $('#example').dataTable( { + * "stateSave": true, + * "stateLoadParams": function (settings, data) { + * data.oSearch.sSearch = ""; + * } + * } ); + * } ); + * + * @example + * // Disallow state loading by returning false + * $(document).ready( function() { + * $('#example').dataTable( { + * "stateSave": true, + * "stateLoadParams": function (settings, data) { + * return false; + * } + * } ); + * } ); + */ + "fnStateLoadParams": null, + + + /** + * Callback that is called when the state has been loaded from the state saving method + * and the DataTables settings object has been modified as a result of the loaded state. + * @type function + * @param {object} settings DataTables settings object + * @param {object} data The state object that was loaded + * + * @dtopt Callbacks + * @name DataTable.defaults.stateLoaded + * + * @example + * // Show an alert with the filtering value that was saved + * $(document).ready( function() { + * $('#example').dataTable( { + * "stateSave": true, + * "stateLoaded": function (settings, data) { + * alert( 'Saved filter was: '+data.oSearch.sSearch ); + * } + * } ); + * } ); + */ + "fnStateLoaded": null, + + + /** + * Save the table state. This function allows you to define where and how the state + * information for the table is stored By default DataTables will use `localStorage` + * but you might wish to use a server-side database or cookies. + * @type function + * @member + * @param {object} settings DataTables settings object + * @param {object} data The state object to be saved + * + * @dtopt Callbacks + * @name DataTable.defaults.stateSaveCallback + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "stateSave": true, + * "stateSaveCallback": function (settings, data) { + * // Send an Ajax request to the server with the state object + * $.ajax( { + * "url": "/state_save", + * "data": data, + * "dataType": "json", + * "method": "POST" + * "success": function () {} + * } ); + * } + * } ); + * } ); + */ + "fnStateSaveCallback": function ( settings, data ) { + try { + (settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem( + 'DataTables_'+settings.sInstance+'_'+location.pathname, + JSON.stringify( data ) + ); + } catch (e) {} + }, + + + /** + * Callback which allows modification of the state to be saved. Called when the table + * has changed state a new state save is required. This method allows modification of + * the state saving object prior to actually doing the save, including addition or + * other state properties or modification. Note that for plug-in authors, you should + * use the `stateSaveParams` event to save parameters for a plug-in. + * @type function + * @param {object} settings DataTables settings object + * @param {object} data The state object to be saved + * + * @dtopt Callbacks + * @name DataTable.defaults.stateSaveParams + * + * @example + * // Remove a saved filter, so filtering is never saved + * $(document).ready( function() { + * $('#example').dataTable( { + * "stateSave": true, + * "stateSaveParams": function (settings, data) { + * data.oSearch.sSearch = ""; + * } + * } ); + * } ); + */ + "fnStateSaveParams": null, + + + /** + * Duration for which the saved state information is considered valid. After this period + * has elapsed the state will be returned to the default. + * Value is given in seconds. + * @type int + * @default 7200 (2 hours) + * + * @dtopt Options + * @name DataTable.defaults.stateDuration + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "stateDuration": 60*60*24; // 1 day + * } ); + * } ) + */ + "iStateDuration": 7200, + + + /** + * When enabled DataTables will not make a request to the server for the first + * page draw - rather it will use the data already on the page (no sorting etc + * will be applied to it), thus saving on an XHR at load time. `deferLoading` + * is used to indicate that deferred loading is required, but it is also used + * to tell DataTables how many records there are in the full table (allowing + * the information element and pagination to be displayed correctly). In the case + * where a filtering is applied to the table on initial load, this can be + * indicated by giving the parameter as an array, where the first element is + * the number of records available after filtering and the second element is the + * number of records without filtering (allowing the table information element + * to be shown correctly). + * @type int | array + * @default null + * + * @dtopt Options + * @name DataTable.defaults.deferLoading + * + * @example + * // 57 records available in the table, no filtering applied + * $(document).ready( function() { + * $('#example').dataTable( { + * "serverSide": true, + * "ajax": "scripts/server_processing.php", + * "deferLoading": 57 + * } ); + * } ); + * + * @example + * // 57 records after filtering, 100 without filtering (an initial filter applied) + * $(document).ready( function() { + * $('#example').dataTable( { + * "serverSide": true, + * "ajax": "scripts/server_processing.php", + * "deferLoading": [ 57, 100 ], + * "search": { + * "search": "my_filter" + * } + * } ); + * } ); + */ + "iDeferLoading": null, + + + /** + * Number of rows to display on a single page when using pagination. If + * feature enabled (`lengthChange`) then the end user will be able to override + * this to a custom setting using a pop-up menu. + * @type int + * @default 10 + * + * @dtopt Options + * @name DataTable.defaults.pageLength + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "pageLength": 50 + * } ); + * } ) + */ + "iDisplayLength": 10, + + + /** + * Define the starting point for data display when using DataTables with + * pagination. Note that this parameter is the number of records, rather than + * the page number, so if you have 10 records per page and want to start on + * the third page, it should be "20". + * @type int + * @default 0 + * + * @dtopt Options + * @name DataTable.defaults.displayStart + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "displayStart": 20 + * } ); + * } ) + */ + "iDisplayStart": 0, + + + /** + * By default DataTables allows keyboard navigation of the table (sorting, paging, + * and filtering) by adding a `tabindex` attribute to the required elements. This + * allows you to tab through the controls and press the enter key to activate them. + * The tabindex is default 0, meaning that the tab follows the flow of the document. + * You can overrule this using this parameter if you wish. Use a value of -1 to + * disable built-in keyboard navigation. + * @type int + * @default 0 + * + * @dtopt Options + * @name DataTable.defaults.tabIndex + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "tabIndex": 1 + * } ); + * } ); + */ + "iTabIndex": 0, + + + /** + * Classes that DataTables assigns to the various components and features + * that it adds to the HTML table. This allows classes to be configured + * during initialisation in addition to through the static + * {@link DataTable.ext.oStdClasses} object). + * @namespace + * @name DataTable.defaults.classes + */ + "oClasses": {}, + + + /** + * All strings that DataTables uses in the user interface that it creates + * are defined in this object, allowing you to modified them individually or + * completely replace them all as required. + * @namespace + * @name DataTable.defaults.language + */ + "oLanguage": { + /** + * Strings that are used for WAI-ARIA labels and controls only (these are not + * actually visible on the page, but will be read by screenreaders, and thus + * must be internationalised as well). + * @namespace + * @name DataTable.defaults.language.aria + */ + "oAria": { + /** + * ARIA label that is added to the table headers when the column may be + * sorted ascending by activing the column (click or return when focused). + * Note that the column header is prefixed to this string. + * @type string + * @default : activate to sort column ascending + * + * @dtopt Language + * @name DataTable.defaults.language.aria.sortAscending + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "aria": { + * "sortAscending": " - click/return to sort ascending" + * } + * } + * } ); + * } ); + */ + "sSortAscending": ": activate to sort column ascending", + + /** + * ARIA label that is added to the table headers when the column may be + * sorted descending by activing the column (click or return when focused). + * Note that the column header is prefixed to this string. + * @type string + * @default : activate to sort column ascending + * + * @dtopt Language + * @name DataTable.defaults.language.aria.sortDescending + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "aria": { + * "sortDescending": " - click/return to sort descending" + * } + * } + * } ); + * } ); + */ + "sSortDescending": ": activate to sort column descending" + }, + + /** + * Pagination string used by DataTables for the built-in pagination + * control types. + * @namespace + * @name DataTable.defaults.language.paginate + */ + "oPaginate": { + /** + * Text to use when using the 'full_numbers' type of pagination for the + * button to take the user to the first page. + * @type string + * @default First + * + * @dtopt Language + * @name DataTable.defaults.language.paginate.first + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "paginate": { + * "first": "First page" + * } + * } + * } ); + * } ); + */ + "sFirst": "First", + + + /** + * Text to use when using the 'full_numbers' type of pagination for the + * button to take the user to the last page. + * @type string + * @default Last + * + * @dtopt Language + * @name DataTable.defaults.language.paginate.last + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "paginate": { + * "last": "Last page" + * } + * } + * } ); + * } ); + */ + "sLast": "Last", + + + /** + * Text to use for the 'next' pagination button (to take the user to the + * next page). + * @type string + * @default Next + * + * @dtopt Language + * @name DataTable.defaults.language.paginate.next + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "paginate": { + * "next": "Next page" + * } + * } + * } ); + * } ); + */ + "sNext": "Next", + + + /** + * Text to use for the 'previous' pagination button (to take the user to + * the previous page). + * @type string + * @default Previous + * + * @dtopt Language + * @name DataTable.defaults.language.paginate.previous + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "paginate": { + * "previous": "Previous page" + * } + * } + * } ); + * } ); + */ + "sPrevious": "Previous" + }, + + /** + * This string is shown in preference to `zeroRecords` when the table is + * empty of data (regardless of filtering). Note that this is an optional + * parameter - if it is not given, the value of `zeroRecords` will be used + * instead (either the default or given value). + * @type string + * @default No data available in table + * + * @dtopt Language + * @name DataTable.defaults.language.emptyTable + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "emptyTable": "No data available in table" + * } + * } ); + * } ); + */ + "sEmptyTable": "No data available in table", + + + /** + * This string gives information to the end user about the information + * that is current on display on the page. The following tokens can be + * used in the string and will be dynamically replaced as the table + * display updates. This tokens can be placed anywhere in the string, or + * removed as needed by the language requires: + * + * * `\_START\_` - Display index of the first record on the current page + * * `\_END\_` - Display index of the last record on the current page + * * `\_TOTAL\_` - Number of records in the table after filtering + * * `\_MAX\_` - Number of records in the table without filtering + * * `\_PAGE\_` - Current page number + * * `\_PAGES\_` - Total number of pages of data in the table + * + * @type string + * @default Showing _START_ to _END_ of _TOTAL_ entries + * + * @dtopt Language + * @name DataTable.defaults.language.info + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "info": "Showing page _PAGE_ of _PAGES_" + * } + * } ); + * } ); + */ + "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries", + + + /** + * Display information string for when the table is empty. Typically the + * format of this string should match `info`. + * @type string + * @default Showing 0 to 0 of 0 entries + * + * @dtopt Language + * @name DataTable.defaults.language.infoEmpty + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "infoEmpty": "No entries to show" + * } + * } ); + * } ); + */ + "sInfoEmpty": "Showing 0 to 0 of 0 entries", + + + /** + * When a user filters the information in a table, this string is appended + * to the information (`info`) to give an idea of how strong the filtering + * is. The variable _MAX_ is dynamically updated. + * @type string + * @default (filtered from _MAX_ total entries) + * + * @dtopt Language + * @name DataTable.defaults.language.infoFiltered + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "infoFiltered": " - filtering from _MAX_ records" + * } + * } ); + * } ); + */ + "sInfoFiltered": "(filtered from _MAX_ total entries)", + + + /** + * If can be useful to append extra information to the info string at times, + * and this variable does exactly that. This information will be appended to + * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are + * being used) at all times. + * @type string + * @default Empty string + * + * @dtopt Language + * @name DataTable.defaults.language.infoPostFix + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "infoPostFix": "All records shown are derived from real information." + * } + * } ); + * } ); + */ + "sInfoPostFix": "", + + + /** + * This decimal place operator is a little different from the other + * language options since DataTables doesn't output floating point + * numbers, so it won't ever use this for display of a number. Rather, + * what this parameter does is modify the sort methods of the table so + * that numbers which are in a format which has a character other than + * a period (`.`) as a decimal place will be sorted numerically. + * + * Note that numbers with different decimal places cannot be shown in + * the same table and still be sortable, the table must be consistent. + * However, multiple different tables on the page can use different + * decimal place characters. + * @type string + * @default + * + * @dtopt Language + * @name DataTable.defaults.language.decimal + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "decimal": "," + * "thousands": "." + * } + * } ); + * } ); + */ + "sDecimal": "", + + + /** + * DataTables has a build in number formatter (`formatNumber`) which is + * used to format large numbers that are used in the table information. + * By default a comma is used, but this can be trivially changed to any + * character you wish with this parameter. + * @type string + * @default , + * + * @dtopt Language + * @name DataTable.defaults.language.thousands + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "thousands": "'" + * } + * } ); + * } ); + */ + "sThousands": ",", + + + /** + * Detail the action that will be taken when the drop down menu for the + * pagination length option is changed. The '_MENU_' variable is replaced + * with a default select list of 10, 25, 50 and 100, and can be replaced + * with a custom select box if required. + * @type string + * @default Show _MENU_ entries + * + * @dtopt Language + * @name DataTable.defaults.language.lengthMenu + * + * @example + * // Language change only + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "lengthMenu": "Display _MENU_ records" + * } + * } ); + * } ); + * + * @example + * // Language and options change + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "lengthMenu": 'Display records' + * } + * } ); + * } ); + */ + "sLengthMenu": "Show _MENU_ entries", + + + /** + * When using Ajax sourced data and during the first draw when DataTables is + * gathering the data, this message is shown in an empty row in the table to + * indicate to the end user the the data is being loaded. Note that this + * parameter is not used when loading data by server-side processing, just + * Ajax sourced data with client-side processing. + * @type string + * @default Loading... + * + * @dtopt Language + * @name DataTable.defaults.language.loadingRecords + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "loadingRecords": "Please wait - loading..." + * } + * } ); + * } ); + */ + "sLoadingRecords": "Loading...", + + + /** + * Text which is displayed when the table is processing a user action + * (usually a sort command or similar). + * @type string + * @default Processing... + * + * @dtopt Language + * @name DataTable.defaults.language.processing + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "processing": "DataTables is currently busy" + * } + * } ); + * } ); + */ + "sProcessing": "Processing...", + + + /** + * Details the actions that will be taken when the user types into the + * filtering input text box. The variable "_INPUT_", if used in the string, + * is replaced with the HTML text box for the filtering input allowing + * control over where it appears in the string. If "_INPUT_" is not given + * then the input box is appended to the string automatically. + * @type string + * @default Search: + * + * @dtopt Language + * @name DataTable.defaults.language.search + * + * @example + * // Input text box will be appended at the end automatically + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "search": "Filter records:" + * } + * } ); + * } ); + * + * @example + * // Specify where the filter should appear + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "search": "Apply filter _INPUT_ to table" + * } + * } ); + * } ); + */ + "sSearch": "Search:", + + + /** + * Assign a `placeholder` attribute to the search `input` element + * @type string + * @default + * + * @dtopt Language + * @name DataTable.defaults.language.searchPlaceholder + */ + "sSearchPlaceholder": "", + + + /** + * All of the language information can be stored in a file on the + * server-side, which DataTables will look up if this parameter is passed. + * It must store the URL of the language file, which is in a JSON format, + * and the object has the same properties as the oLanguage object in the + * initialiser object (i.e. the above parameters). Please refer to one of + * the example language files to see how this works in action. + * @type string + * @default Empty string - i.e. disabled + * + * @dtopt Language + * @name DataTable.defaults.language.url + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "url": "http://www.sprymedia.co.uk/dataTables/lang.txt" + * } + * } ); + * } ); + */ + "sUrl": "", + + + /** + * Text shown inside the table records when the is no information to be + * displayed after filtering. `emptyTable` is shown when there is simply no + * information in the table at all (regardless of filtering). + * @type string + * @default No matching records found + * + * @dtopt Language + * @name DataTable.defaults.language.zeroRecords + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "language": { + * "zeroRecords": "No records to display" + * } + * } ); + * } ); + */ + "sZeroRecords": "No matching records found" + }, + + + /** + * This parameter allows you to have define the global filtering state at + * initialisation time. As an object the `search` parameter must be + * defined, but all other parameters are optional. When `regex` is true, + * the search string will be treated as a regular expression, when false + * (default) it will be treated as a straight string. When `smart` + * DataTables will use it's smart filtering methods (to word match at + * any point in the data), when false this will not be done. + * @namespace + * @extends DataTable.models.oSearch + * + * @dtopt Options + * @name DataTable.defaults.search + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "search": {"search": "Initial search"} + * } ); + * } ) + */ + "oSearch": $.extend( {}, DataTable.models.oSearch ), + + + /** + * __Deprecated__ The functionality provided by this parameter has now been + * superseded by that provided through `ajax`, which should be used instead. + * + * By default DataTables will look for the property `data` (or `aaData` for + * compatibility with DataTables 1.9-) when obtaining data from an Ajax + * source or for server-side processing - this parameter allows that + * property to be changed. You can use Javascript dotted object notation to + * get a data source for multiple levels of nesting. + * @type string + * @default data + * + * @dtopt Options + * @dtopt Server-side + * @name DataTable.defaults.ajaxDataProp + * + * @deprecated 1.10. Please use `ajax` for this functionality now. + */ + "sAjaxDataProp": "data", + + + /** + * __Deprecated__ The functionality provided by this parameter has now been + * superseded by that provided through `ajax`, which should be used instead. + * + * You can instruct DataTables to load data from an external + * source using this parameter (use aData if you want to pass data in you + * already have). Simply provide a url a JSON object can be obtained from. + * @type string + * @default null + * + * @dtopt Options + * @dtopt Server-side + * @name DataTable.defaults.ajaxSource + * + * @deprecated 1.10. Please use `ajax` for this functionality now. + */ + "sAjaxSource": null, + + + /** + * This initialisation variable allows you to specify exactly where in the + * DOM you want DataTables to inject the various controls it adds to the page + * (for example you might want the pagination controls at the top of the + * table). DIV elements (with or without a custom class) can also be added to + * aid styling. The follow syntax is used: + *
    + *
  • The following options are allowed: + *
      + *
    • 'l' - Length changing
    • + *
    • 'f' - Filtering input
    • + *
    • 't' - The table!
    • + *
    • 'i' - Information
    • + *
    • 'p' - Pagination
    • + *
    • 'r' - pRocessing
    • + *
    + *
  • + *
  • The following constants are allowed: + *
      + *
    • 'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')
    • + *
    • 'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')
    • + *
    + *
  • + *
  • The following syntax is expected: + *
      + *
    • '<' and '>' - div elements
    • + *
    • '<"class" and '>' - div with a class
    • + *
    • '<"#id" and '>' - div with an ID
    • + *
    + *
  • + *
  • Examples: + *
      + *
    • '<"wrapper"flipt>'
    • + *
    • '<lf<t>ip>'
    • + *
    + *
  • + *
+ * @type string + * @default lfrtip (when `jQueryUI` is false) or + * <"H"lfr>t<"F"ip> (when `jQueryUI` is true) + * + * @dtopt Options + * @name DataTable.defaults.dom + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "dom": '<"top"i>rt<"bottom"flp><"clear">' + * } ); + * } ); + */ + "sDom": "lfrtip", + + + /** + * Search delay option. This will throttle full table searches that use the + * DataTables provided search input element (it does not effect calls to + * `dt-api search()`, providing a delay before the search is made. + * @type integer + * @default 0 + * + * @dtopt Options + * @name DataTable.defaults.searchDelay + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "searchDelay": 200 + * } ); + * } ) + */ + "searchDelay": null, + + + /** + * DataTables features four different built-in options for the buttons to + * display for pagination control: + * + * * `simple` - 'Previous' and 'Next' buttons only + * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers + * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons + * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus + * page numbers + * + * Further methods can be added using {@link DataTable.ext.oPagination}. + * @type string + * @default simple_numbers + * + * @dtopt Options + * @name DataTable.defaults.pagingType + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "pagingType": "full_numbers" + * } ); + * } ) + */ + "sPaginationType": "simple_numbers", + + + /** + * Enable horizontal scrolling. When a table is too wide to fit into a + * certain layout, or you have a large number of columns in the table, you + * can enable x-scrolling to show the table in a viewport, which can be + * scrolled. This property can be `true` which will allow the table to + * scroll horizontally when needed, or any CSS unit, or a number (in which + * case it will be treated as a pixel measurement). Setting as simply `true` + * is recommended. + * @type boolean|string + * @default blank string - i.e. disabled + * + * @dtopt Features + * @name DataTable.defaults.scrollX + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "scrollX": true, + * "scrollCollapse": true + * } ); + * } ); + */ + "sScrollX": "", + + + /** + * This property can be used to force a DataTable to use more width than it + * might otherwise do when x-scrolling is enabled. For example if you have a + * table which requires to be well spaced, this parameter is useful for + * "over-sizing" the table, and thus forcing scrolling. This property can by + * any CSS unit, or a number (in which case it will be treated as a pixel + * measurement). + * @type string + * @default blank string - i.e. disabled + * + * @dtopt Options + * @name DataTable.defaults.scrollXInner + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "scrollX": "100%", + * "scrollXInner": "110%" + * } ); + * } ); + */ + "sScrollXInner": "", + + + /** + * Enable vertical scrolling. Vertical scrolling will constrain the DataTable + * to the given height, and enable scrolling for any data which overflows the + * current viewport. This can be used as an alternative to paging to display + * a lot of data in a small area (although paging and scrolling can both be + * enabled at the same time). This property can be any CSS unit, or a number + * (in which case it will be treated as a pixel measurement). + * @type string + * @default blank string - i.e. disabled + * + * @dtopt Features + * @name DataTable.defaults.scrollY + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "scrollY": "200px", + * "paginate": false + * } ); + * } ); + */ + "sScrollY": "", + + + /** + * __Deprecated__ The functionality provided by this parameter has now been + * superseded by that provided through `ajax`, which should be used instead. + * + * Set the HTTP method that is used to make the Ajax call for server-side + * processing or Ajax sourced data. + * @type string + * @default GET + * + * @dtopt Options + * @dtopt Server-side + * @name DataTable.defaults.serverMethod + * + * @deprecated 1.10. Please use `ajax` for this functionality now. + */ + "sServerMethod": "GET", + + + /** + * DataTables makes use of renderers when displaying HTML elements for + * a table. These renderers can be added or modified by plug-ins to + * generate suitable mark-up for a site. For example the Bootstrap + * integration plug-in for DataTables uses a paging button renderer to + * display pagination buttons in the mark-up required by Bootstrap. + * + * For further information about the renderers available see + * DataTable.ext.renderer + * @type string|object + * @default null + * + * @name DataTable.defaults.renderer + * + */ + "renderer": null, + + + /** + * Set the data property name that DataTables should use to get a row's id + * to set as the `id` property in the node. + * @type string + * @default DT_RowId + * + * @name DataTable.defaults.rowId + */ + "rowId": "DT_RowId" + }; + + _fnHungarianMap( DataTable.defaults ); + + + + /* + * Developer note - See note in model.defaults.js about the use of Hungarian + * notation and camel case. + */ + + /** + * Column options that can be given to DataTables at initialisation time. + * @namespace + */ + DataTable.defaults.column = { + /** + * Define which column(s) an order will occur on for this column. This + * allows a column's ordering to take multiple columns into account when + * doing a sort or use the data from a different column. For example first + * name / last name columns make sense to do a multi-column sort over the + * two columns. + * @type array|int + * @default null Takes the value of the column index automatically + * + * @name DataTable.defaults.column.orderData + * @dtopt Columns + * + * @example + * // Using `columnDefs` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columnDefs": [ + * { "orderData": [ 0, 1 ], "targets": [ 0 ] }, + * { "orderData": [ 1, 0 ], "targets": [ 1 ] }, + * { "orderData": 2, "targets": [ 2 ] } + * ] + * } ); + * } ); + * + * @example + * // Using `columns` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columns": [ + * { "orderData": [ 0, 1 ] }, + * { "orderData": [ 1, 0 ] }, + * { "orderData": 2 }, + * null, + * null + * ] + * } ); + * } ); + */ + "aDataSort": null, + "iDataSort": -1, + + + /** + * You can control the default ordering direction, and even alter the + * behaviour of the sort handler (i.e. only allow ascending ordering etc) + * using this parameter. + * @type array + * @default [ 'asc', 'desc' ] + * + * @name DataTable.defaults.column.orderSequence + * @dtopt Columns + * + * @example + * // Using `columnDefs` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columnDefs": [ + * { "orderSequence": [ "asc" ], "targets": [ 1 ] }, + * { "orderSequence": [ "desc", "asc", "asc" ], "targets": [ 2 ] }, + * { "orderSequence": [ "desc" ], "targets": [ 3 ] } + * ] + * } ); + * } ); + * + * @example + * // Using `columns` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columns": [ + * null, + * { "orderSequence": [ "asc" ] }, + * { "orderSequence": [ "desc", "asc", "asc" ] }, + * { "orderSequence": [ "desc" ] }, + * null + * ] + * } ); + * } ); + */ + "asSorting": [ 'asc', 'desc' ], + + + /** + * Enable or disable filtering on the data in this column. + * @type boolean + * @default true + * + * @name DataTable.defaults.column.searchable + * @dtopt Columns + * + * @example + * // Using `columnDefs` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columnDefs": [ + * { "searchable": false, "targets": [ 0 ] } + * ] } ); + * } ); + * + * @example + * // Using `columns` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columns": [ + * { "searchable": false }, + * null, + * null, + * null, + * null + * ] } ); + * } ); + */ + "bSearchable": true, + + + /** + * Enable or disable ordering on this column. + * @type boolean + * @default true + * + * @name DataTable.defaults.column.orderable + * @dtopt Columns + * + * @example + * // Using `columnDefs` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columnDefs": [ + * { "orderable": false, "targets": [ 0 ] } + * ] } ); + * } ); + * + * @example + * // Using `columns` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columns": [ + * { "orderable": false }, + * null, + * null, + * null, + * null + * ] } ); + * } ); + */ + "bSortable": true, + + + /** + * Enable or disable the display of this column. + * @type boolean + * @default true + * + * @name DataTable.defaults.column.visible + * @dtopt Columns + * + * @example + * // Using `columnDefs` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columnDefs": [ + * { "visible": false, "targets": [ 0 ] } + * ] } ); + * } ); + * + * @example + * // Using `columns` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columns": [ + * { "visible": false }, + * null, + * null, + * null, + * null + * ] } ); + * } ); + */ + "bVisible": true, + + + /** + * Developer definable function that is called whenever a cell is created (Ajax source, + * etc) or processed for input (DOM source). This can be used as a compliment to mRender + * allowing you to modify the DOM element (add background colour for example) when the + * element is available. + * @type function + * @param {element} td The TD node that has been created + * @param {*} cellData The Data for the cell + * @param {array|object} rowData The data for the whole row + * @param {int} row The row index for the aoData data store + * @param {int} col The column index for aoColumns + * + * @name DataTable.defaults.column.createdCell + * @dtopt Columns + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "columnDefs": [ { + * "targets": [3], + * "createdCell": function (td, cellData, rowData, row, col) { + * if ( cellData == "1.7" ) { + * $(td).css('color', 'blue') + * } + * } + * } ] + * }); + * } ); + */ + "fnCreatedCell": null, + + + /** + * This parameter has been replaced by `data` in DataTables to ensure naming + * consistency. `dataProp` can still be used, as there is backwards + * compatibility in DataTables for this option, but it is strongly + * recommended that you use `data` in preference to `dataProp`. + * @name DataTable.defaults.column.dataProp + */ + + + /** + * This property can be used to read data from any data source property, + * including deeply nested objects / properties. `data` can be given in a + * number of different ways which effect its behaviour: + * + * * `integer` - treated as an array index for the data source. This is the + * default that DataTables uses (incrementally increased for each column). + * * `string` - read an object property from the data source. There are + * three 'special' options that can be used in the string to alter how + * DataTables reads the data from the source object: + * * `.` - Dotted Javascript notation. Just as you use a `.` in + * Javascript to read from nested objects, so to can the options + * specified in `data`. For example: `browser.version` or + * `browser.name`. If your object parameter name contains a period, use + * `\\` to escape it - i.e. `first\\.name`. + * * `[]` - Array notation. DataTables can automatically combine data + * from and array source, joining the data with the characters provided + * between the two brackets. For example: `name[, ]` would provide a + * comma-space separated list from the source array. If no characters + * are provided between the brackets, the original array source is + * returned. + * * `()` - Function notation. Adding `()` to the end of a parameter will + * execute a function of the name given. For example: `browser()` for a + * simple function on the data source, `browser.version()` for a + * function in a nested property or even `browser().version` to get an + * object property if the function called returns an object. Note that + * function notation is recommended for use in `render` rather than + * `data` as it is much simpler to use as a renderer. + * * `null` - use the original data source for the row rather than plucking + * data directly from it. This action has effects on two other + * initialisation options: + * * `defaultContent` - When null is given as the `data` option and + * `defaultContent` is specified for the column, the value defined by + * `defaultContent` will be used for the cell. + * * `render` - When null is used for the `data` option and the `render` + * option is specified for the column, the whole data source for the + * row is used for the renderer. + * * `function` - the function given will be executed whenever DataTables + * needs to set or get the data for a cell in the column. The function + * takes three parameters: + * * Parameters: + * * `{array|object}` The data source for the row + * * `{string}` The type call data requested - this will be 'set' when + * setting data or 'filter', 'display', 'type', 'sort' or undefined + * when gathering data. Note that when `undefined` is given for the + * type DataTables expects to get the raw data for the object back< + * * `{*}` Data to set when the second parameter is 'set'. + * * Return: + * * The return value from the function is not required when 'set' is + * the type of call, but otherwise the return is what will be used + * for the data requested. + * + * Note that `data` is a getter and setter option. If you just require + * formatting of data for output, you will likely want to use `render` which + * is simply a getter and thus simpler to use. + * + * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The + * name change reflects the flexibility of this property and is consistent + * with the naming of mRender. If 'mDataProp' is given, then it will still + * be used by DataTables, as it automatically maps the old name to the new + * if required. + * + * @type string|int|function|null + * @default null Use automatically calculated column index + * + * @name DataTable.defaults.column.data + * @dtopt Columns + * + * @example + * // Read table data from objects + * // JSON structure for each row: + * // { + * // "engine": {value}, + * // "browser": {value}, + * // "platform": {value}, + * // "version": {value}, + * // "grade": {value} + * // } + * $(document).ready( function() { + * $('#example').dataTable( { + * "ajaxSource": "sources/objects.txt", + * "columns": [ + * { "data": "engine" }, + * { "data": "browser" }, + * { "data": "platform" }, + * { "data": "version" }, + * { "data": "grade" } + * ] + * } ); + * } ); + * + * @example + * // Read information from deeply nested objects + * // JSON structure for each row: + * // { + * // "engine": {value}, + * // "browser": {value}, + * // "platform": { + * // "inner": {value} + * // }, + * // "details": [ + * // {value}, {value} + * // ] + * // } + * $(document).ready( function() { + * $('#example').dataTable( { + * "ajaxSource": "sources/deep.txt", + * "columns": [ + * { "data": "engine" }, + * { "data": "browser" }, + * { "data": "platform.inner" }, + * { "data": "platform.details.0" }, + * { "data": "platform.details.1" } + * ] + * } ); + * } ); + * + * @example + * // Using `data` as a function to provide different information for + * // sorting, filtering and display. In this case, currency (price) + * $(document).ready( function() { + * $('#example').dataTable( { + * "columnDefs": [ { + * "targets": [ 0 ], + * "data": function ( source, type, val ) { + * if (type === 'set') { + * source.price = val; + * // Store the computed dislay and filter values for efficiency + * source.price_display = val=="" ? "" : "$"+numberFormat(val); + * source.price_filter = val=="" ? "" : "$"+numberFormat(val)+" "+val; + * return; + * } + * else if (type === 'display') { + * return source.price_display; + * } + * else if (type === 'filter') { + * return source.price_filter; + * } + * // 'sort', 'type' and undefined all just use the integer + * return source.price; + * } + * } ] + * } ); + * } ); + * + * @example + * // Using default content + * $(document).ready( function() { + * $('#example').dataTable( { + * "columnDefs": [ { + * "targets": [ 0 ], + * "data": null, + * "defaultContent": "Click to edit" + * } ] + * } ); + * } ); + * + * @example + * // Using array notation - outputting a list from an array + * $(document).ready( function() { + * $('#example').dataTable( { + * "columnDefs": [ { + * "targets": [ 0 ], + * "data": "name[, ]" + * } ] + * } ); + * } ); + * + */ + "mData": null, + + + /** + * This property is the rendering partner to `data` and it is suggested that + * when you want to manipulate data for display (including filtering, + * sorting etc) without altering the underlying data for the table, use this + * property. `render` can be considered to be the the read only companion to + * `data` which is read / write (then as such more complex). Like `data` + * this option can be given in a number of different ways to effect its + * behaviour: + * + * * `integer` - treated as an array index for the data source. This is the + * default that DataTables uses (incrementally increased for each column). + * * `string` - read an object property from the data source. There are + * three 'special' options that can be used in the string to alter how + * DataTables reads the data from the source object: + * * `.` - Dotted Javascript notation. Just as you use a `.` in + * Javascript to read from nested objects, so to can the options + * specified in `data`. For example: `browser.version` or + * `browser.name`. If your object parameter name contains a period, use + * `\\` to escape it - i.e. `first\\.name`. + * * `[]` - Array notation. DataTables can automatically combine data + * from and array source, joining the data with the characters provided + * between the two brackets. For example: `name[, ]` would provide a + * comma-space separated list from the source array. If no characters + * are provided between the brackets, the original array source is + * returned. + * * `()` - Function notation. Adding `()` to the end of a parameter will + * execute a function of the name given. For example: `browser()` for a + * simple function on the data source, `browser.version()` for a + * function in a nested property or even `browser().version` to get an + * object property if the function called returns an object. + * * `object` - use different data for the different data types requested by + * DataTables ('filter', 'display', 'type' or 'sort'). The property names + * of the object is the data type the property refers to and the value can + * defined using an integer, string or function using the same rules as + * `render` normally does. Note that an `_` option _must_ be specified. + * This is the default value to use if you haven't specified a value for + * the data type requested by DataTables. + * * `function` - the function given will be executed whenever DataTables + * needs to set or get the data for a cell in the column. The function + * takes three parameters: + * * Parameters: + * * {array|object} The data source for the row (based on `data`) + * * {string} The type call data requested - this will be 'filter', + * 'display', 'type' or 'sort'. + * * {array|object} The full data source for the row (not based on + * `data`) + * * Return: + * * The return value from the function is what will be used for the + * data requested. + * + * @type string|int|function|object|null + * @default null Use the data source value. + * + * @name DataTable.defaults.column.render + * @dtopt Columns + * + * @example + * // Create a comma separated list from an array of objects + * $(document).ready( function() { + * $('#example').dataTable( { + * "ajaxSource": "sources/deep.txt", + * "columns": [ + * { "data": "engine" }, + * { "data": "browser" }, + * { + * "data": "platform", + * "render": "[, ].name" + * } + * ] + * } ); + * } ); + * + * @example + * // Execute a function to obtain data + * $(document).ready( function() { + * $('#example').dataTable( { + * "columnDefs": [ { + * "targets": [ 0 ], + * "data": null, // Use the full data source object for the renderer's source + * "render": "browserName()" + * } ] + * } ); + * } ); + * + * @example + * // As an object, extracting different data for the different types + * // This would be used with a data source such as: + * // { "phone": 5552368, "phone_filter": "5552368 555-2368", "phone_display": "555-2368" } + * // Here the `phone` integer is used for sorting and type detection, while `phone_filter` + * // (which has both forms) is used for filtering for if a user inputs either format, while + * // the formatted phone number is the one that is shown in the table. + * $(document).ready( function() { + * $('#example').dataTable( { + * "columnDefs": [ { + * "targets": [ 0 ], + * "data": null, // Use the full data source object for the renderer's source + * "render": { + * "_": "phone", + * "filter": "phone_filter", + * "display": "phone_display" + * } + * } ] + * } ); + * } ); + * + * @example + * // Use as a function to create a link from the data source + * $(document).ready( function() { + * $('#example').dataTable( { + * "columnDefs": [ { + * "targets": [ 0 ], + * "data": "download_link", + * "render": function ( data, type, full ) { + * return 'Download'; + * } + * } ] + * } ); + * } ); + */ + "mRender": null, + + + /** + * Change the cell type created for the column - either TD cells or TH cells. This + * can be useful as TH cells have semantic meaning in the table body, allowing them + * to act as a header for a row (you may wish to add scope='row' to the TH elements). + * @type string + * @default td + * + * @name DataTable.defaults.column.cellType + * @dtopt Columns + * + * @example + * // Make the first column use TH cells + * $(document).ready( function() { + * $('#example').dataTable( { + * "columnDefs": [ { + * "targets": [ 0 ], + * "cellType": "th" + * } ] + * } ); + * } ); + */ + "sCellType": "td", + + + /** + * Class to give to each cell in this column. + * @type string + * @default Empty string + * + * @name DataTable.defaults.column.class + * @dtopt Columns + * + * @example + * // Using `columnDefs` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columnDefs": [ + * { "class": "my_class", "targets": [ 0 ] } + * ] + * } ); + * } ); + * + * @example + * // Using `columns` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columns": [ + * { "class": "my_class" }, + * null, + * null, + * null, + * null + * ] + * } ); + * } ); + */ + "sClass": "", + + /** + * When DataTables calculates the column widths to assign to each column, + * it finds the longest string in each column and then constructs a + * temporary table and reads the widths from that. The problem with this + * is that "mmm" is much wider then "iiii", but the latter is a longer + * string - thus the calculation can go wrong (doing it properly and putting + * it into an DOM object and measuring that is horribly(!) slow). Thus as + * a "work around" we provide this option. It will append its value to the + * text that is found to be the longest string for the column - i.e. padding. + * Generally you shouldn't need this! + * @type string + * @default Empty string + * + * @name DataTable.defaults.column.contentPadding + * @dtopt Columns + * + * @example + * // Using `columns` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columns": [ + * null, + * null, + * null, + * { + * "contentPadding": "mmm" + * } + * ] + * } ); + * } ); + */ + "sContentPadding": "", + + + /** + * Allows a default value to be given for a column's data, and will be used + * whenever a null data source is encountered (this can be because `data` + * is set to null, or because the data source itself is null). + * @type string + * @default null + * + * @name DataTable.defaults.column.defaultContent + * @dtopt Columns + * + * @example + * // Using `columnDefs` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columnDefs": [ + * { + * "data": null, + * "defaultContent": "Edit", + * "targets": [ -1 ] + * } + * ] + * } ); + * } ); + * + * @example + * // Using `columns` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columns": [ + * null, + * null, + * null, + * { + * "data": null, + * "defaultContent": "Edit" + * } + * ] + * } ); + * } ); + */ + "sDefaultContent": null, + + + /** + * This parameter is only used in DataTables' server-side processing. It can + * be exceptionally useful to know what columns are being displayed on the + * client side, and to map these to database fields. When defined, the names + * also allow DataTables to reorder information from the server if it comes + * back in an unexpected order (i.e. if you switch your columns around on the + * client-side, your server-side code does not also need updating). + * @type string + * @default Empty string + * + * @name DataTable.defaults.column.name + * @dtopt Columns + * + * @example + * // Using `columnDefs` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columnDefs": [ + * { "name": "engine", "targets": [ 0 ] }, + * { "name": "browser", "targets": [ 1 ] }, + * { "name": "platform", "targets": [ 2 ] }, + * { "name": "version", "targets": [ 3 ] }, + * { "name": "grade", "targets": [ 4 ] } + * ] + * } ); + * } ); + * + * @example + * // Using `columns` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columns": [ + * { "name": "engine" }, + * { "name": "browser" }, + * { "name": "platform" }, + * { "name": "version" }, + * { "name": "grade" } + * ] + * } ); + * } ); + */ + "sName": "", + + + /** + * Defines a data source type for the ordering which can be used to read + * real-time information from the table (updating the internally cached + * version) prior to ordering. This allows ordering to occur on user + * editable elements such as form inputs. + * @type string + * @default std + * + * @name DataTable.defaults.column.orderDataType + * @dtopt Columns + * + * @example + * // Using `columnDefs` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columnDefs": [ + * { "orderDataType": "dom-text", "targets": [ 2, 3 ] }, + * { "type": "numeric", "targets": [ 3 ] }, + * { "orderDataType": "dom-select", "targets": [ 4 ] }, + * { "orderDataType": "dom-checkbox", "targets": [ 5 ] } + * ] + * } ); + * } ); + * + * @example + * // Using `columns` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columns": [ + * null, + * null, + * { "orderDataType": "dom-text" }, + * { "orderDataType": "dom-text", "type": "numeric" }, + * { "orderDataType": "dom-select" }, + * { "orderDataType": "dom-checkbox" } + * ] + * } ); + * } ); + */ + "sSortDataType": "std", + + + /** + * The title of this column. + * @type string + * @default null Derived from the 'TH' value for this column in the + * original HTML table. + * + * @name DataTable.defaults.column.title + * @dtopt Columns + * + * @example + * // Using `columnDefs` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columnDefs": [ + * { "title": "My column title", "targets": [ 0 ] } + * ] + * } ); + * } ); + * + * @example + * // Using `columns` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columns": [ + * { "title": "My column title" }, + * null, + * null, + * null, + * null + * ] + * } ); + * } ); + */ + "sTitle": null, + + + /** + * The type allows you to specify how the data for this column will be + * ordered. Four types (string, numeric, date and html (which will strip + * HTML tags before ordering)) are currently available. Note that only date + * formats understood by Javascript's Date() object will be accepted as type + * date. For example: "Mar 26, 2008 5:03 PM". May take the values: 'string', + * 'numeric', 'date' or 'html' (by default). Further types can be adding + * through plug-ins. + * @type string + * @default null Auto-detected from raw data + * + * @name DataTable.defaults.column.type + * @dtopt Columns + * + * @example + * // Using `columnDefs` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columnDefs": [ + * { "type": "html", "targets": [ 0 ] } + * ] + * } ); + * } ); + * + * @example + * // Using `columns` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columns": [ + * { "type": "html" }, + * null, + * null, + * null, + * null + * ] + * } ); + * } ); + */ + "sType": null, + + + /** + * Defining the width of the column, this parameter may take any CSS value + * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not + * been given a specific width through this interface ensuring that the table + * remains readable. + * @type string + * @default null Automatic + * + * @name DataTable.defaults.column.width + * @dtopt Columns + * + * @example + * // Using `columnDefs` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columnDefs": [ + * { "width": "20%", "targets": [ 0 ] } + * ] + * } ); + * } ); + * + * @example + * // Using `columns` + * $(document).ready( function() { + * $('#example').dataTable( { + * "columns": [ + * { "width": "20%" }, + * null, + * null, + * null, + * null + * ] + * } ); + * } ); + */ + "sWidth": null + }; + + _fnHungarianMap( DataTable.defaults.column ); + + + + /** + * DataTables settings object - this holds all the information needed for a + * given table, including configuration, data and current application of the + * table options. DataTables does not have a single instance for each DataTable + * with the settings attached to that instance, but rather instances of the + * DataTable "class" are created on-the-fly as needed (typically by a + * $().dataTable() call) and the settings object is then applied to that + * instance. + * + * Note that this object is related to {@link DataTable.defaults} but this + * one is the internal data store for DataTables's cache of columns. It should + * NOT be manipulated outside of DataTables. Any configuration should be done + * through the initialisation options. + * @namespace + * @todo Really should attach the settings object to individual instances so we + * don't need to create new instances on each $().dataTable() call (if the + * table already exists). It would also save passing oSettings around and + * into every single function. However, this is a very significant + * architecture change for DataTables and will almost certainly break + * backwards compatibility with older installations. This is something that + * will be done in 2.0. + */ + DataTable.models.oSettings = { + /** + * Primary features of DataTables and their enablement state. + * @namespace + */ + "oFeatures": { + + /** + * Flag to say if DataTables should automatically try to calculate the + * optimum table and columns widths (true) or not (false). + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bAutoWidth": null, + + /** + * Delay the creation of TR and TD elements until they are actually + * needed by a driven page draw. This can give a significant speed + * increase for Ajax source and Javascript source data, but makes no + * difference at all fro DOM and server-side processing tables. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bDeferRender": null, + + /** + * Enable filtering on the table or not. Note that if this is disabled + * then there is no filtering at all on the table, including fnFilter. + * To just remove the filtering input use sDom and remove the 'f' option. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bFilter": null, + + /** + * Table information element (the 'Showing x of y records' div) enable + * flag. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bInfo": null, + + /** + * Present a user control allowing the end user to change the page size + * when pagination is enabled. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bLengthChange": null, + + /** + * Pagination enabled or not. Note that if this is disabled then length + * changing must also be disabled. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bPaginate": null, + + /** + * Processing indicator enable flag whenever DataTables is enacting a + * user request - typically an Ajax request for server-side processing. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bProcessing": null, + + /** + * Server-side processing enabled flag - when enabled DataTables will + * get all data from the server for every draw - there is no filtering, + * sorting or paging done on the client-side. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bServerSide": null, + + /** + * Sorting enablement flag. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bSort": null, + + /** + * Multi-column sorting + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bSortMulti": null, + + /** + * Apply a class to the columns which are being sorted to provide a + * visual highlight or not. This can slow things down when enabled since + * there is a lot of DOM interaction. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bSortClasses": null, + + /** + * State saving enablement flag. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bStateSave": null + }, + + + /** + * Scrolling settings for a table. + * @namespace + */ + "oScroll": { + /** + * When the table is shorter in height than sScrollY, collapse the + * table container down to the height of the table (when true). + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bCollapse": null, + + /** + * Width of the scrollbar for the web-browser's platform. Calculated + * during table initialisation. + * @type int + * @default 0 + */ + "iBarWidth": 0, + + /** + * Viewport width for horizontal scrolling. Horizontal scrolling is + * disabled if an empty string. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type string + */ + "sX": null, + + /** + * Width to expand the table to when using x-scrolling. Typically you + * should not need to use this. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type string + * @deprecated + */ + "sXInner": null, + + /** + * Viewport height for vertical scrolling. Vertical scrolling is disabled + * if an empty string. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type string + */ + "sY": null + }, + + /** + * Language information for the table. + * @namespace + * @extends DataTable.defaults.oLanguage + */ + "oLanguage": { + /** + * Information callback function. See + * {@link DataTable.defaults.fnInfoCallback} + * @type function + * @default null + */ + "fnInfoCallback": null + }, + + /** + * Browser support parameters + * @namespace + */ + "oBrowser": { + /** + * Indicate if the browser incorrectly calculates width:100% inside a + * scrolling element (IE6/7) + * @type boolean + * @default false + */ + "bScrollOversize": false, + + /** + * Determine if the vertical scrollbar is on the right or left of the + * scrolling container - needed for rtl language layout, although not + * all browsers move the scrollbar (Safari). + * @type boolean + * @default false + */ + "bScrollbarLeft": false, + + /** + * Flag for if `getBoundingClientRect` is fully supported or not + * @type boolean + * @default false + */ + "bBounding": false, + + /** + * Browser scrollbar width + * @type integer + * @default 0 + */ + "barWidth": 0 + }, + + + "ajax": null, + + + /** + * Array referencing the nodes which are used for the features. The + * parameters of this object match what is allowed by sDom - i.e. + *
    + *
  • 'l' - Length changing
  • + *
  • 'f' - Filtering input
  • + *
  • 't' - The table!
  • + *
  • 'i' - Information
  • + *
  • 'p' - Pagination
  • + *
  • 'r' - pRocessing
  • + *
+ * @type array + * @default [] + */ + "aanFeatures": [], + + /** + * Store data information - see {@link DataTable.models.oRow} for detailed + * information. + * @type array + * @default [] + */ + "aoData": [], + + /** + * Array of indexes which are in the current display (after filtering etc) + * @type array + * @default [] + */ + "aiDisplay": [], + + /** + * Array of indexes for display - no filtering + * @type array + * @default [] + */ + "aiDisplayMaster": [], + + /** + * Map of row ids to data indexes + * @type object + * @default {} + */ + "aIds": {}, + + /** + * Store information about each column that is in use + * @type array + * @default [] + */ + "aoColumns": [], + + /** + * Store information about the table's header + * @type array + * @default [] + */ + "aoHeader": [], + + /** + * Store information about the table's footer + * @type array + * @default [] + */ + "aoFooter": [], + + /** + * Store the applied global search information in case we want to force a + * research or compare the old search to a new one. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @namespace + * @extends DataTable.models.oSearch + */ + "oPreviousSearch": {}, + + /** + * Store the applied search for each column - see + * {@link DataTable.models.oSearch} for the format that is used for the + * filtering information for each column. + * @type array + * @default [] + */ + "aoPreSearchCols": [], + + /** + * Sorting that is applied to the table. Note that the inner arrays are + * used in the following manner: + *
    + *
  • Index 0 - column number
  • + *
  • Index 1 - current sorting direction
  • + *
+ * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type array + * @todo These inner arrays should really be objects + */ + "aaSorting": null, + + /** + * Sorting that is always applied to the table (i.e. prefixed in front of + * aaSorting). + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type array + * @default [] + */ + "aaSortingFixed": [], + + /** + * Classes to use for the striping of a table. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type array + * @default [] + */ + "asStripeClasses": null, + + /** + * If restoring a table - we should restore its striping classes as well + * @type array + * @default [] + */ + "asDestroyStripes": [], + + /** + * If restoring a table - we should restore its width + * @type int + * @default 0 + */ + "sDestroyWidth": 0, + + /** + * Callback functions array for every time a row is inserted (i.e. on a draw). + * @type array + * @default [] + */ + "aoRowCallback": [], + + /** + * Callback functions for the header on each draw. + * @type array + * @default [] + */ + "aoHeaderCallback": [], + + /** + * Callback function for the footer on each draw. + * @type array + * @default [] + */ + "aoFooterCallback": [], + + /** + * Array of callback functions for draw callback functions + * @type array + * @default [] + */ + "aoDrawCallback": [], + + /** + * Array of callback functions for row created function + * @type array + * @default [] + */ + "aoRowCreatedCallback": [], + + /** + * Callback functions for just before the table is redrawn. A return of + * false will be used to cancel the draw. + * @type array + * @default [] + */ + "aoPreDrawCallback": [], + + /** + * Callback functions for when the table has been initialised. + * @type array + * @default [] + */ + "aoInitComplete": [], + + + /** + * Callbacks for modifying the settings to be stored for state saving, prior to + * saving state. + * @type array + * @default [] + */ + "aoStateSaveParams": [], + + /** + * Callbacks for modifying the settings that have been stored for state saving + * prior to using the stored values to restore the state. + * @type array + * @default [] + */ + "aoStateLoadParams": [], + + /** + * Callbacks for operating on the settings object once the saved state has been + * loaded + * @type array + * @default [] + */ + "aoStateLoaded": [], + + /** + * Cache the table ID for quick access + * @type string + * @default Empty string + */ + "sTableId": "", + + /** + * The TABLE node for the main table + * @type node + * @default null + */ + "nTable": null, + + /** + * Permanent ref to the thead element + * @type node + * @default null + */ + "nTHead": null, + + /** + * Permanent ref to the tfoot element - if it exists + * @type node + * @default null + */ + "nTFoot": null, + + /** + * Permanent ref to the tbody element + * @type node + * @default null + */ + "nTBody": null, + + /** + * Cache the wrapper node (contains all DataTables controlled elements) + * @type node + * @default null + */ + "nTableWrapper": null, + + /** + * Indicate if when using server-side processing the loading of data + * should be deferred until the second draw. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + * @default false + */ + "bDeferLoading": false, + + /** + * Indicate if all required information has been read in + * @type boolean + * @default false + */ + "bInitialised": false, + + /** + * Information about open rows. Each object in the array has the parameters + * 'nTr' and 'nParent' + * @type array + * @default [] + */ + "aoOpenRows": [], + + /** + * Dictate the positioning of DataTables' control elements - see + * {@link DataTable.model.oInit.sDom}. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type string + * @default null + */ + "sDom": null, + + /** + * Search delay (in mS) + * @type integer + * @default null + */ + "searchDelay": null, + + /** + * Which type of pagination should be used. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type string + * @default two_button + */ + "sPaginationType": "two_button", + + /** + * The state duration (for `stateSave`) in seconds. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type int + * @default 0 + */ + "iStateDuration": 0, + + /** + * Array of callback functions for state saving. Each array element is an + * object with the following parameters: + *
    + *
  • function:fn - function to call. Takes two parameters, oSettings + * and the JSON string to save that has been thus far created. Returns + * a JSON string to be inserted into a json object + * (i.e. '"param": [ 0, 1, 2]')
  • + *
  • string:sName - name of callback
  • + *
+ * @type array + * @default [] + */ + "aoStateSave": [], + + /** + * Array of callback functions for state loading. Each array element is an + * object with the following parameters: + *
    + *
  • function:fn - function to call. Takes two parameters, oSettings + * and the object stored. May return false to cancel state loading
  • + *
  • string:sName - name of callback
  • + *
+ * @type array + * @default [] + */ + "aoStateLoad": [], + + /** + * State that was saved. Useful for back reference + * @type object + * @default null + */ + "oSavedState": null, + + /** + * State that was loaded. Useful for back reference + * @type object + * @default null + */ + "oLoadedState": null, + + /** + * Source url for AJAX data for the table. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type string + * @default null + */ + "sAjaxSource": null, + + /** + * Property from a given object from which to read the table data from. This + * can be an empty string (when not server-side processing), in which case + * it is assumed an an array is given directly. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type string + */ + "sAjaxDataProp": null, + + /** + * Note if draw should be blocked while getting data + * @type boolean + * @default true + */ + "bAjaxDataGet": true, + + /** + * The last jQuery XHR object that was used for server-side data gathering. + * This can be used for working with the XHR information in one of the + * callbacks + * @type object + * @default null + */ + "jqXHR": null, + + /** + * JSON returned from the server in the last Ajax request + * @type object + * @default undefined + */ + "json": undefined, + + /** + * Data submitted as part of the last Ajax request + * @type object + * @default undefined + */ + "oAjaxData": undefined, + + /** + * Function to get the server-side data. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type function + */ + "fnServerData": null, + + /** + * Functions which are called prior to sending an Ajax request so extra + * parameters can easily be sent to the server + * @type array + * @default [] + */ + "aoServerParams": [], + + /** + * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if + * required). + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type string + */ + "sServerMethod": null, + + /** + * Format numbers for display. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type function + */ + "fnFormatNumber": null, + + /** + * List of options that can be used for the user selectable length menu. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type array + * @default [] + */ + "aLengthMenu": null, + + /** + * Counter for the draws that the table does. Also used as a tracker for + * server-side processing + * @type int + * @default 0 + */ + "iDraw": 0, + + /** + * Indicate if a redraw is being done - useful for Ajax + * @type boolean + * @default false + */ + "bDrawing": false, + + /** + * Draw index (iDraw) of the last error when parsing the returned data + * @type int + * @default -1 + */ + "iDrawError": -1, + + /** + * Paging display length + * @type int + * @default 10 + */ + "_iDisplayLength": 10, + + /** + * Paging start point - aiDisplay index + * @type int + * @default 0 + */ + "_iDisplayStart": 0, + + /** + * Server-side processing - number of records in the result set + * (i.e. before filtering), Use fnRecordsTotal rather than + * this property to get the value of the number of records, regardless of + * the server-side processing setting. + * @type int + * @default 0 + * @private + */ + "_iRecordsTotal": 0, + + /** + * Server-side processing - number of records in the current display set + * (i.e. after filtering). Use fnRecordsDisplay rather than + * this property to get the value of the number of records, regardless of + * the server-side processing setting. + * @type boolean + * @default 0 + * @private + */ + "_iRecordsDisplay": 0, + + /** + * Flag to indicate if jQuery UI marking and classes should be used. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bJUI": null, + + /** + * The classes to use for the table + * @type object + * @default {} + */ + "oClasses": {}, + + /** + * Flag attached to the settings object so you can check in the draw + * callback if filtering has been done in the draw. Deprecated in favour of + * events. + * @type boolean + * @default false + * @deprecated + */ + "bFiltered": false, + + /** + * Flag attached to the settings object so you can check in the draw + * callback if sorting has been done in the draw. Deprecated in favour of + * events. + * @type boolean + * @default false + * @deprecated + */ + "bSorted": false, + + /** + * Indicate that if multiple rows are in the header and there is more than + * one unique cell per column, if the top one (true) or bottom one (false) + * should be used for sorting / title by DataTables. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bSortCellsTop": null, + + /** + * Initialisation object that is used for the table + * @type object + * @default null + */ + "oInit": null, + + /** + * Destroy callback functions - for plug-ins to attach themselves to the + * destroy so they can clean up markup and events. + * @type array + * @default [] + */ + "aoDestroyCallback": [], + + + /** + * Get the number of records in the current record set, before filtering + * @type function + */ + "fnRecordsTotal": function () + { + return _fnDataSource( this ) == 'ssp' ? + this._iRecordsTotal * 1 : + this.aiDisplayMaster.length; + }, + + /** + * Get the number of records in the current record set, after filtering + * @type function + */ + "fnRecordsDisplay": function () + { + return _fnDataSource( this ) == 'ssp' ? + this._iRecordsDisplay * 1 : + this.aiDisplay.length; + }, + + /** + * Get the display end point - aiDisplay index + * @type function + */ + "fnDisplayEnd": function () + { + var + len = this._iDisplayLength, + start = this._iDisplayStart, + calc = start + len, + records = this.aiDisplay.length, + features = this.oFeatures, + paginate = features.bPaginate; + + if ( features.bServerSide ) { + return paginate === false || len === -1 ? + start + records : + Math.min( start+len, this._iRecordsDisplay ); + } + else { + return ! paginate || calc>records || len===-1 ? + records : + calc; + } + }, + + /** + * The DataTables object for this table + * @type object + * @default null + */ + "oInstance": null, + + /** + * Unique identifier for each instance of the DataTables object. If there + * is an ID on the table node, then it takes that value, otherwise an + * incrementing internal counter is used. + * @type string + * @default null + */ + "sInstance": null, + + /** + * tabindex attribute value that is added to DataTables control elements, allowing + * keyboard navigation of the table and its controls. + */ + "iTabIndex": 0, + + /** + * DIV container for the footer scrolling table if scrolling + */ + "nScrollHead": null, + + /** + * DIV container for the footer scrolling table if scrolling + */ + "nScrollFoot": null, + + /** + * Last applied sort + * @type array + * @default [] + */ + "aLastSort": [], + + /** + * Stored plug-in instances + * @type object + * @default {} + */ + "oPlugins": {}, + + /** + * Function used to get a row's id from the row's data + * @type function + * @default null + */ + "rowIdFn": null, + + /** + * Data location where to store a row's id + * @type string + * @default null + */ + "rowId": null + }; + + /** + * Extension object for DataTables that is used to provide all extension + * options. + * + * Note that the `DataTable.ext` object is available through + * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is + * also aliased to `jQuery.fn.dataTableExt` for historic reasons. + * @namespace + * @extends DataTable.models.ext + */ + + + /** + * DataTables extensions + * + * This namespace acts as a collection area for plug-ins that can be used to + * extend DataTables capabilities. Indeed many of the build in methods + * use this method to provide their own capabilities (sorting methods for + * example). + * + * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy + * reasons + * + * @namespace + */ + DataTable.ext = _ext = { + /** + * Buttons. For use with the Buttons extension for DataTables. This is + * defined here so other extensions can define buttons regardless of load + * order. It is _not_ used by DataTables core. + * + * @type object + * @default {} + */ + buttons: {}, + + + /** + * Element class names + * + * @type object + * @default {} + */ + classes: {}, + + + /** + * DataTables build type (expanded by the download builder) + * + * @type string + */ + builder: "-source-", + + + /** + * Error reporting. + * + * How should DataTables report an error. Can take the value 'alert', + * 'throw', 'none' or a function. + * + * @type string|function + * @default alert + */ + errMode: "alert", + + + /** + * Feature plug-ins. + * + * This is an array of objects which describe the feature plug-ins that are + * available to DataTables. These feature plug-ins are then available for + * use through the `dom` initialisation option. + * + * Each feature plug-in is described by an object which must have the + * following properties: + * + * * `fnInit` - function that is used to initialise the plug-in, + * * `cFeature` - a character so the feature can be enabled by the `dom` + * instillation option. This is case sensitive. + * + * The `fnInit` function has the following input parameters: + * + * 1. `{object}` DataTables settings object: see + * {@link DataTable.models.oSettings} + * + * And the following return is expected: + * + * * {node|null} The element which contains your feature. Note that the + * return may also be void if your plug-in does not require to inject any + * DOM elements into DataTables control (`dom`) - for example this might + * be useful when developing a plug-in which allows table control via + * keyboard entry + * + * @type array + * + * @example + * $.fn.dataTable.ext.features.push( { + * "fnInit": function( oSettings ) { + * return new TableTools( { "oDTSettings": oSettings } ); + * }, + * "cFeature": "T" + * } ); + */ + feature: [], + + + /** + * Row searching. + * + * This method of searching is complimentary to the default type based + * searching, and a lot more comprehensive as it allows you complete control + * over the searching logic. Each element in this array is a function + * (parameters described below) that is called for every row in the table, + * and your logic decides if it should be included in the searching data set + * or not. + * + * Searching functions have the following input parameters: + * + * 1. `{object}` DataTables settings object: see + * {@link DataTable.models.oSettings} + * 2. `{array|object}` Data for the row to be processed (same as the + * original format that was passed in as the data source, or an array + * from a DOM data source + * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which + * can be useful to retrieve the `TR` element if you need DOM interaction. + * + * And the following return is expected: + * + * * {boolean} Include the row in the searched result set (true) or not + * (false) + * + * Note that as with the main search ability in DataTables, technically this + * is "filtering", since it is subtractive. However, for consistency in + * naming we call it searching here. + * + * @type array + * @default [] + * + * @example + * // The following example shows custom search being applied to the + * // fourth column (i.e. the data[3] index) based on two input values + * // from the end-user, matching the data in a certain range. + * $.fn.dataTable.ext.search.push( + * function( settings, data, dataIndex ) { + * var min = document.getElementById('min').value * 1; + * var max = document.getElementById('max').value * 1; + * var version = data[3] == "-" ? 0 : data[3]*1; + * + * if ( min == "" && max == "" ) { + * return true; + * } + * else if ( min == "" && version < max ) { + * return true; + * } + * else if ( min < version && "" == max ) { + * return true; + * } + * else if ( min < version && version < max ) { + * return true; + * } + * return false; + * } + * ); + */ + search: [], + + + /** + * Selector extensions + * + * The `selector` option can be used to extend the options available for the + * selector modifier options (`selector-modifier` object data type) that + * each of the three built in selector types offer (row, column and cell + + * their plural counterparts). For example the Select extension uses this + * mechanism to provide an option to select only rows, columns and cells + * that have been marked as selected by the end user (`{selected: true}`), + * which can be used in conjunction with the existing built in selector + * options. + * + * Each property is an array to which functions can be pushed. The functions + * take three attributes: + * + * * Settings object for the host table + * * Options object (`selector-modifier` object type) + * * Array of selected item indexes + * + * The return is an array of the resulting item indexes after the custom + * selector has been applied. + * + * @type object + */ + selector: { + cell: [], + column: [], + row: [] + }, + + + /** + * Internal functions, exposed for used in plug-ins. + * + * Please note that you should not need to use the internal methods for + * anything other than a plug-in (and even then, try to avoid if possible). + * The internal function may change between releases. + * + * @type object + * @default {} + */ + internal: {}, + + + /** + * Legacy configuration options. Enable and disable legacy options that + * are available in DataTables. + * + * @type object + */ + legacy: { + /** + * Enable / disable DataTables 1.9 compatible server-side processing + * requests + * + * @type boolean + * @default null + */ + ajax: null + }, + + + /** + * Pagination plug-in methods. + * + * Each entry in this object is a function and defines which buttons should + * be shown by the pagination rendering method that is used for the table: + * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the + * buttons are displayed in the document, while the functions here tell it + * what buttons to display. This is done by returning an array of button + * descriptions (what each button will do). + * + * Pagination types (the four built in options and any additional plug-in + * options defined here) can be used through the `paginationType` + * initialisation parameter. + * + * The functions defined take two parameters: + * + * 1. `{int} page` The current page index + * 2. `{int} pages` The number of pages in the table + * + * Each function is expected to return an array where each element of the + * array can be one of: + * + * * `first` - Jump to first page when activated + * * `last` - Jump to last page when activated + * * `previous` - Show previous page when activated + * * `next` - Show next page when activated + * * `{int}` - Show page of the index given + * * `{array}` - A nested array containing the above elements to add a + * containing 'DIV' element (might be useful for styling). + * + * Note that DataTables v1.9- used this object slightly differently whereby + * an object with two functions would be defined for each plug-in. That + * ability is still supported by DataTables 1.10+ to provide backwards + * compatibility, but this option of use is now decremented and no longer + * documented in DataTables 1.10+. + * + * @type object + * @default {} + * + * @example + * // Show previous, next and current page buttons only + * $.fn.dataTableExt.oPagination.current = function ( page, pages ) { + * return [ 'previous', page, 'next' ]; + * }; + */ + pager: {}, + + + renderer: { + pageButton: {}, + header: {} + }, + + + /** + * Ordering plug-ins - custom data source + * + * The extension options for ordering of data available here is complimentary + * to the default type based ordering that DataTables typically uses. It + * allows much greater control over the the data that is being used to + * order a column, but is necessarily therefore more complex. + * + * This type of ordering is useful if you want to do ordering based on data + * live from the DOM (for example the contents of an 'input' element) rather + * than just the static string that DataTables knows of. + * + * The way these plug-ins work is that you create an array of the values you + * wish to be ordering for the column in question and then return that + * array. The data in the array much be in the index order of the rows in + * the table (not the currently ordering order!). Which order data gathering + * function is run here depends on the `dt-init columns.orderDataType` + * parameter that is used for the column (if any). + * + * The functions defined take two parameters: + * + * 1. `{object}` DataTables settings object: see + * {@link DataTable.models.oSettings} + * 2. `{int}` Target column index + * + * Each function is expected to return an array: + * + * * `{array}` Data for the column to be ordering upon + * + * @type array + * + * @example + * // Ordering using `input` node values + * $.fn.dataTable.ext.order['dom-text'] = function ( settings, col ) + * { + * return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) { + * return $('input', td).val(); + * } ); + * } + */ + order: {}, + + + /** + * Type based plug-ins. + * + * Each column in DataTables has a type assigned to it, either by automatic + * detection or by direct assignment using the `type` option for the column. + * The type of a column will effect how it is ordering and search (plug-ins + * can also make use of the column type if required). + * + * @namespace + */ + type: { + /** + * Type detection functions. + * + * The functions defined in this object are used to automatically detect + * a column's type, making initialisation of DataTables super easy, even + * when complex data is in the table. + * + * The functions defined take two parameters: + * + * 1. `{*}` Data from the column cell to be analysed + * 2. `{settings}` DataTables settings object. This can be used to + * perform context specific type detection - for example detection + * based on language settings such as using a comma for a decimal + * place. Generally speaking the options from the settings will not + * be required + * + * Each function is expected to return: + * + * * `{string|null}` Data type detected, or null if unknown (and thus + * pass it on to the other type detection functions. + * + * @type array + * + * @example + * // Currency type detection plug-in: + * $.fn.dataTable.ext.type.detect.push( + * function ( data, settings ) { + * // Check the numeric part + * if ( ! $.isNumeric( data.substring(1) ) ) { + * return null; + * } + * + * // Check prefixed by currency + * if ( data.charAt(0) == '$' || data.charAt(0) == '£' ) { + * return 'currency'; + * } + * return null; + * } + * ); + */ + detect: [], + + + /** + * Type based search formatting. + * + * The type based searching functions can be used to pre-format the + * data to be search on. For example, it can be used to strip HTML + * tags or to de-format telephone numbers for numeric only searching. + * + * Note that is a search is not defined for a column of a given type, + * no search formatting will be performed. + * + * Pre-processing of searching data plug-ins - When you assign the sType + * for a column (or have it automatically detected for you by DataTables + * or a type detection plug-in), you will typically be using this for + * custom sorting, but it can also be used to provide custom searching + * by allowing you to pre-processing the data and returning the data in + * the format that should be searched upon. This is done by adding + * functions this object with a parameter name which matches the sType + * for that target column. This is the corollary of afnSortData + * for searching data. + * + * The functions defined take a single parameter: + * + * 1. `{*}` Data from the column cell to be prepared for searching + * + * Each function is expected to return: + * + * * `{string|null}` Formatted string that will be used for the searching. + * + * @type object + * @default {} + * + * @example + * $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) { + * return d.replace(/\n/g," ").replace( /<.*?>/g, "" ); + * } + */ + search: {}, + + + /** + * Type based ordering. + * + * The column type tells DataTables what ordering to apply to the table + * when a column is sorted upon. The order for each type that is defined, + * is defined by the functions available in this object. + * + * Each ordering option can be described by three properties added to + * this object: + * + * * `{type}-pre` - Pre-formatting function + * * `{type}-asc` - Ascending order function + * * `{type}-desc` - Descending order function + * + * All three can be used together, only `{type}-pre` or only + * `{type}-asc` and `{type}-desc` together. It is generally recommended + * that only `{type}-pre` is used, as this provides the optimal + * implementation in terms of speed, although the others are provided + * for compatibility with existing Javascript sort functions. + * + * `{type}-pre`: Functions defined take a single parameter: + * + * 1. `{*}` Data from the column cell to be prepared for ordering + * + * And return: + * + * * `{*}` Data to be sorted upon + * + * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort + * functions, taking two parameters: + * + * 1. `{*}` Data to compare to the second parameter + * 2. `{*}` Data to compare to the first parameter + * + * And returning: + * + * * `{*}` Ordering match: <0 if first parameter should be sorted lower + * than the second parameter, ===0 if the two parameters are equal and + * >0 if the first parameter should be sorted height than the second + * parameter. + * + * @type object + * @default {} + * + * @example + * // Numeric ordering of formatted numbers with a pre-formatter + * $.extend( $.fn.dataTable.ext.type.order, { + * "string-pre": function(x) { + * a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" ); + * return parseFloat( a ); + * } + * } ); + * + * @example + * // Case-sensitive string ordering, with no pre-formatting method + * $.extend( $.fn.dataTable.ext.order, { + * "string-case-asc": function(x,y) { + * return ((x < y) ? -1 : ((x > y) ? 1 : 0)); + * }, + * "string-case-desc": function(x,y) { + * return ((x < y) ? 1 : ((x > y) ? -1 : 0)); + * } + * } ); + */ + order: {} + }, + + /** + * Unique DataTables instance counter + * + * @type int + * @private + */ + _unique: 0, + + + // + // Depreciated + // The following properties are retained for backwards compatiblity only. + // The should not be used in new projects and will be removed in a future + // version + // + + /** + * Version check function. + * @type function + * @depreciated Since 1.10 + */ + fnVersionCheck: DataTable.fnVersionCheck, + + + /** + * Index for what 'this' index API functions should use + * @type int + * @deprecated Since v1.10 + */ + iApiIndex: 0, + + + /** + * jQuery UI class container + * @type object + * @deprecated Since v1.10 + */ + oJUIClasses: {}, + + + /** + * Software version + * @type string + * @deprecated Since v1.10 + */ + sVersion: DataTable.version + }; + + + // + // Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts + // + $.extend( _ext, { + afnFiltering: _ext.search, + aTypes: _ext.type.detect, + ofnSearch: _ext.type.search, + oSort: _ext.type.order, + afnSortData: _ext.order, + aoFeatures: _ext.feature, + oApi: _ext.internal, + oStdClasses: _ext.classes, + oPagination: _ext.pager + } ); + + + $.extend( DataTable.ext.classes, { + "sTable": "dataTable", + "sNoFooter": "no-footer", + + /* Paging buttons */ + "sPageButton": "paginate_button", + "sPageButtonActive": "current", + "sPageButtonDisabled": "disabled", + + /* Striping classes */ + "sStripeOdd": "odd", + "sStripeEven": "even", + + /* Empty row */ + "sRowEmpty": "dataTables_empty", + + /* Features */ + "sWrapper": "dataTables_wrapper", + "sFilter": "dataTables_filter", + "sInfo": "dataTables_info", + "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */ + "sLength": "dataTables_length", + "sProcessing": "dataTables_processing", + + /* Sorting */ + "sSortAsc": "sorting_asc", + "sSortDesc": "sorting_desc", + "sSortable": "sorting", /* Sortable in both directions */ + "sSortableAsc": "sorting_asc_disabled", + "sSortableDesc": "sorting_desc_disabled", + "sSortableNone": "sorting_disabled", + "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */ + + /* Filtering */ + "sFilterInput": "", + + /* Page length */ + "sLengthSelect": "", + + /* Scrolling */ + "sScrollWrapper": "dataTables_scroll", + "sScrollHead": "dataTables_scrollHead", + "sScrollHeadInner": "dataTables_scrollHeadInner", + "sScrollBody": "dataTables_scrollBody", + "sScrollFoot": "dataTables_scrollFoot", + "sScrollFootInner": "dataTables_scrollFootInner", + + /* Misc */ + "sHeaderTH": "", + "sFooterTH": "", + + // Deprecated + "sSortJUIAsc": "", + "sSortJUIDesc": "", + "sSortJUI": "", + "sSortJUIAscAllowed": "", + "sSortJUIDescAllowed": "", + "sSortJUIWrapper": "", + "sSortIcon": "", + "sJUIHeader": "", + "sJUIFooter": "" + } ); + + + (function() { + + // Reused strings for better compression. Closure compiler appears to have a + // weird edge case where it is trying to expand strings rather than use the + // variable version. This results in about 200 bytes being added, for very + // little preference benefit since it this run on script load only. + var _empty = ''; + _empty = ''; + + var _stateDefault = _empty + 'ui-state-default'; + var _sortIcon = _empty + 'css_right ui-icon ui-icon-'; + var _headerFooter = _empty + 'fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix'; + + $.extend( DataTable.ext.oJUIClasses, DataTable.ext.classes, { + /* Full numbers paging buttons */ + "sPageButton": "fg-button ui-button "+_stateDefault, + "sPageButtonActive": "ui-state-disabled", + "sPageButtonDisabled": "ui-state-disabled", + + /* Features */ + "sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+ + "ui-buttonset-multi paging_", /* Note that the type is postfixed */ + + /* Sorting */ + "sSortAsc": _stateDefault+" sorting_asc", + "sSortDesc": _stateDefault+" sorting_desc", + "sSortable": _stateDefault+" sorting", + "sSortableAsc": _stateDefault+" sorting_asc_disabled", + "sSortableDesc": _stateDefault+" sorting_desc_disabled", + "sSortableNone": _stateDefault+" sorting_disabled", + "sSortJUIAsc": _sortIcon+"triangle-1-n", + "sSortJUIDesc": _sortIcon+"triangle-1-s", + "sSortJUI": _sortIcon+"carat-2-n-s", + "sSortJUIAscAllowed": _sortIcon+"carat-1-n", + "sSortJUIDescAllowed": _sortIcon+"carat-1-s", + "sSortJUIWrapper": "DataTables_sort_wrapper", + "sSortIcon": "DataTables_sort_icon", + + /* Scrolling */ + "sScrollHead": "dataTables_scrollHead "+_stateDefault, + "sScrollFoot": "dataTables_scrollFoot "+_stateDefault, + + /* Misc */ + "sHeaderTH": _stateDefault, + "sFooterTH": _stateDefault, + "sJUIHeader": _headerFooter+" ui-corner-tl ui-corner-tr", + "sJUIFooter": _headerFooter+" ui-corner-bl ui-corner-br" + } ); + + }()); + + + + var extPagination = DataTable.ext.pager; + + function _numbers ( page, pages ) { + var + numbers = [], + buttons = extPagination.numbers_length, + half = Math.floor( buttons / 2 ), + i = 1; + + if ( pages <= buttons ) { + numbers = _range( 0, pages ); + } + else if ( page <= half ) { + numbers = _range( 0, buttons-2 ); + numbers.push( 'ellipsis' ); + numbers.push( pages-1 ); + } + else if ( page >= pages - 1 - half ) { + numbers = _range( pages-(buttons-2), pages ); + numbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6 + numbers.splice( 0, 0, 0 ); + } + else { + numbers = _range( page-half+2, page+half-1 ); + numbers.push( 'ellipsis' ); + numbers.push( pages-1 ); + numbers.splice( 0, 0, 'ellipsis' ); + numbers.splice( 0, 0, 0 ); + } + + numbers.DT_el = 'span'; + return numbers; + } + + + $.extend( extPagination, { + simple: function ( page, pages ) { + return [ 'previous', 'next' ]; + }, + + full: function ( page, pages ) { + return [ 'first', 'previous', 'next', 'last' ]; + }, + + numbers: function ( page, pages ) { + return [ _numbers(page, pages) ]; + }, + + simple_numbers: function ( page, pages ) { + return [ 'previous', _numbers(page, pages), 'next' ]; + }, + + full_numbers: function ( page, pages ) { + return [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ]; + }, + + // For testing and plug-ins to use + _numbers: _numbers, + + // Number of number buttons (including ellipsis) to show. _Must be odd!_ + numbers_length: 7 + } ); + + + $.extend( true, DataTable.ext.renderer, { + pageButton: { + _: function ( settings, host, idx, buttons, page, pages ) { + var classes = settings.oClasses; + var lang = settings.oLanguage.oPaginate; + var aria = settings.oLanguage.oAria.paginate || {}; + var btnDisplay, btnClass, counter=0; + + var attach = function( container, buttons ) { + var i, ien, node, button; + var clickHandler = function ( e ) { + _fnPageChange( settings, e.data.action, true ); + }; + + for ( i=0, ien=buttons.length ; i' ) + .appendTo( container ); + attach( inner, button ); + } + else { + btnDisplay = null; + btnClass = ''; + + switch ( button ) { + case 'ellipsis': + container.append(''); + break; + + case 'first': + btnDisplay = lang.sFirst; + btnClass = button + (page > 0 ? + '' : ' '+classes.sPageButtonDisabled); + break; + + case 'previous': + btnDisplay = lang.sPrevious; + btnClass = button + (page > 0 ? + '' : ' '+classes.sPageButtonDisabled); + break; + + case 'next': + btnDisplay = lang.sNext; + btnClass = button + (page < pages-1 ? + '' : ' '+classes.sPageButtonDisabled); + break; + + case 'last': + btnDisplay = lang.sLast; + btnClass = button + (page < pages-1 ? + '' : ' '+classes.sPageButtonDisabled); + break; + + default: + btnDisplay = button + 1; + btnClass = page === button ? + classes.sPageButtonActive : ''; + break; + } + + if ( btnDisplay !== null ) { + node = $('', { + 'class': classes.sPageButton+' '+btnClass, + 'aria-controls': settings.sTableId, + 'aria-label': aria[ button ], + 'data-dt-idx': counter, + 'tabindex': settings.iTabIndex, + 'id': idx === 0 && typeof button === 'string' ? + settings.sTableId +'_'+ button : + null + } ) + .html( btnDisplay ) + .appendTo( container ); + + _fnBindAction( + node, {action: button}, clickHandler + ); + + counter++; + } + } + } + }; + + // IE9 throws an 'unknown error' if document.activeElement is used + // inside an iframe or frame. Try / catch the error. Not good for + // accessibility, but neither are frames. + var activeEl; + + try { + // Because this approach is destroying and recreating the paging + // elements, focus is lost on the select button which is bad for + // accessibility. So we want to restore focus once the draw has + // completed + activeEl = $(host).find(document.activeElement).data('dt-idx'); + } + catch (e) {} + + attach( $(host).empty(), buttons ); + + if ( activeEl ) { + $(host).find( '[data-dt-idx='+activeEl+']' ).focus(); + } + } + } + } ); + + + + // Built in type detection. See model.ext.aTypes for information about + // what is required from this methods. + $.extend( DataTable.ext.type.detect, [ + // Plain numbers - first since V8 detects some plain numbers as dates + // e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...). + function ( d, settings ) + { + var decimal = settings.oLanguage.sDecimal; + return _isNumber( d, decimal ) ? 'num'+decimal : null; + }, + + // Dates (only those recognised by the browser's Date.parse) + function ( d, settings ) + { + // V8 will remove any unknown characters at the start and end of the + // expression, leading to false matches such as `$245.12` or `10%` being + // a valid date. See forum thread 18941 for detail. + if ( d && !(d instanceof Date) && ( ! _re_date_start.test(d) || ! _re_date_end.test(d) ) ) { + return null; + } + var parsed = Date.parse(d); + return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null; + }, + + // Formatted numbers + function ( d, settings ) + { + var decimal = settings.oLanguage.sDecimal; + return _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null; + }, + + // HTML numeric + function ( d, settings ) + { + var decimal = settings.oLanguage.sDecimal; + return _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null; + }, + + // HTML numeric, formatted + function ( d, settings ) + { + var decimal = settings.oLanguage.sDecimal; + return _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null; + }, + + // HTML (this is strict checking - there must be html) + function ( d, settings ) + { + return _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ? + 'html' : null; + } + ] ); + + + + // Filter formatting functions. See model.ext.ofnSearch for information about + // what is required from these methods. + // + // Note that additional search methods are added for the html numbers and + // html formatted numbers by `_addNumericSort()` when we know what the decimal + // place is + + + $.extend( DataTable.ext.type.search, { + html: function ( data ) { + return _empty(data) ? + data : + typeof data === 'string' ? + data + .replace( _re_new_lines, " " ) + .replace( _re_html, "" ) : + ''; + }, + + string: function ( data ) { + return _empty(data) ? + data : + typeof data === 'string' ? + data.replace( _re_new_lines, " " ) : + data; + } + } ); + + + + var __numericReplace = function ( d, decimalPlace, re1, re2 ) { + if ( d !== 0 && (!d || d === '-') ) { + return -Infinity; + } + + // If a decimal place other than `.` is used, it needs to be given to the + // function so we can detect it and replace with a `.` which is the only + // decimal place Javascript recognises - it is not locale aware. + if ( decimalPlace ) { + d = _numToDecimal( d, decimalPlace ); + } + + if ( d.replace ) { + if ( re1 ) { + d = d.replace( re1, '' ); + } + + if ( re2 ) { + d = d.replace( re2, '' ); + } + } + + return d * 1; + }; + + + // Add the numeric 'deformatting' functions for sorting and search. This is done + // in a function to provide an easy ability for the language options to add + // additional methods if a non-period decimal place is used. + function _addNumericSort ( decimalPlace ) { + $.each( + { + // Plain numbers + "num": function ( d ) { + return __numericReplace( d, decimalPlace ); + }, + + // Formatted numbers + "num-fmt": function ( d ) { + return __numericReplace( d, decimalPlace, _re_formatted_numeric ); + }, + + // HTML numeric + "html-num": function ( d ) { + return __numericReplace( d, decimalPlace, _re_html ); + }, + + // HTML numeric, formatted + "html-num-fmt": function ( d ) { + return __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric ); + } + }, + function ( key, fn ) { + // Add the ordering method + _ext.type.order[ key+decimalPlace+'-pre' ] = fn; + + // For HTML types add a search formatter that will strip the HTML + if ( key.match(/^html\-/) ) { + _ext.type.search[ key+decimalPlace ] = _ext.type.search.html; + } + } + ); + } + + + // Default sort methods + $.extend( _ext.type.order, { + // Dates + "date-pre": function ( d ) { + return Date.parse( d ) || 0; + }, + + // html + "html-pre": function ( a ) { + return _empty(a) ? + '' : + a.replace ? + a.replace( /<.*?>/g, "" ).toLowerCase() : + a+''; + }, + + // string + "string-pre": function ( a ) { + // This is a little complex, but faster than always calling toString, + // http://jsperf.com/tostring-v-check + return _empty(a) ? + '' : + typeof a === 'string' ? + a.toLowerCase() : + ! a.toString ? + '' : + a.toString(); + }, + + // string-asc and -desc are retained only for compatibility with the old + // sort methods + "string-asc": function ( x, y ) { + return ((x < y) ? -1 : ((x > y) ? 1 : 0)); + }, + + "string-desc": function ( x, y ) { + return ((x < y) ? 1 : ((x > y) ? -1 : 0)); + } + } ); + + + // Numeric sorting types - order doesn't matter here + _addNumericSort( '' ); + + + $.extend( true, DataTable.ext.renderer, { + header: { + _: function ( settings, cell, column, classes ) { + // No additional mark-up required + // Attach a sort listener to update on sort - note that using the + // `DT` namespace will allow the event to be removed automatically + // on destroy, while the `dt` namespaced event is the one we are + // listening for + $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) { + if ( settings !== ctx ) { // need to check this this is the host + return; // table, not a nested one + } + + var colIdx = column.idx; + + cell + .removeClass( + column.sSortingClass +' '+ + classes.sSortAsc +' '+ + classes.sSortDesc + ) + .addClass( columns[ colIdx ] == 'asc' ? + classes.sSortAsc : columns[ colIdx ] == 'desc' ? + classes.sSortDesc : + column.sSortingClass + ); + } ); + }, + + jqueryui: function ( settings, cell, column, classes ) { + $('
') + .addClass( classes.sSortJUIWrapper ) + .append( cell.contents() ) + .append( $('') + .addClass( classes.sSortIcon+' '+column.sSortingClassJUI ) + ) + .appendTo( cell ); + + // Attach a sort listener to update on sort + $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) { + if ( settings !== ctx ) { + return; + } + + var colIdx = column.idx; + + cell + .removeClass( classes.sSortAsc +" "+classes.sSortDesc ) + .addClass( columns[ colIdx ] == 'asc' ? + classes.sSortAsc : columns[ colIdx ] == 'desc' ? + classes.sSortDesc : + column.sSortingClass + ); + + cell + .find( 'span.'+classes.sSortIcon ) + .removeClass( + classes.sSortJUIAsc +" "+ + classes.sSortJUIDesc +" "+ + classes.sSortJUI +" "+ + classes.sSortJUIAscAllowed +" "+ + classes.sSortJUIDescAllowed + ) + .addClass( columns[ colIdx ] == 'asc' ? + classes.sSortJUIAsc : columns[ colIdx ] == 'desc' ? + classes.sSortJUIDesc : + column.sSortingClassJUI + ); + } ); + } + } + } ); + + /* + * Public helper functions. These aren't used internally by DataTables, or + * called by any of the options passed into DataTables, but they can be used + * externally by developers working with DataTables. They are helper functions + * to make working with DataTables a little bit easier. + */ + + var __htmlEscapeEntities = function ( d ) { + return typeof d === 'string' ? + d.replace(//g, '>').replace(/"/g, '"') : + d; + }; + + /** + * Helpers for `columns.render`. + * + * The options defined here can be used with the `columns.render` initialisation + * option to provide a display renderer. The following functions are defined: + * + * * `number` - Will format numeric data (defined by `columns.data`) for + * display, retaining the original unformatted data for sorting and filtering. + * It takes 5 parameters: + * * `string` - Thousands grouping separator + * * `string` - Decimal point indicator + * * `integer` - Number of decimal points to show + * * `string` (optional) - Prefix. + * * `string` (optional) - Postfix (/suffix). + * * `text` - Escape HTML to help prevent XSS attacks. It has no optional + * parameters. + * + * @example + * // Column definition using the number renderer + * { + * data: "salary", + * render: $.fn.dataTable.render.number( '\'', '.', 0, '$' ) + * } + * + * @namespace + */ + DataTable.render = { + number: function ( thousands, decimal, precision, prefix, postfix ) { + return { + display: function ( d ) { + if ( typeof d !== 'number' && typeof d !== 'string' ) { + return d; + } + + var negative = d < 0 ? '-' : ''; + var flo = parseFloat( d ); + + // If NaN then there isn't much formatting that we can do - just + // return immediately, escaping any HTML (this was supposed to + // be a number after all) + if ( isNaN( flo ) ) { + return __htmlEscapeEntities( d ); + } + + d = Math.abs( flo ); + + var intPart = parseInt( d, 10 ); + var floatPart = precision ? + decimal+(d - intPart).toFixed( precision ).substring( 2 ): + ''; + + return negative + (prefix||'') + + intPart.toString().replace( + /\B(?=(\d{3})+(?!\d))/g, thousands + ) + + floatPart + + (postfix||''); + } + }; + }, + + text: function () { + return { + display: __htmlEscapeEntities + }; + } + }; + + + /* + * This is really a good bit rubbish this method of exposing the internal methods + * publicly... - To be fixed in 2.0 using methods on the prototype + */ + + + /** + * Create a wrapper function for exporting an internal functions to an external API. + * @param {string} fn API function name + * @returns {function} wrapped function + * @memberof DataTable#internal + */ + function _fnExternApiFunc (fn) + { + return function() { + var args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat( + Array.prototype.slice.call(arguments) + ); + return DataTable.ext.internal[fn].apply( this, args ); + }; + } + + + /** + * Reference to internal functions for use by plug-in developers. Note that + * these methods are references to internal functions and are considered to be + * private. If you use these methods, be aware that they are liable to change + * between versions. + * @namespace + */ + $.extend( DataTable.ext.internal, { + _fnExternApiFunc: _fnExternApiFunc, + _fnBuildAjax: _fnBuildAjax, + _fnAjaxUpdate: _fnAjaxUpdate, + _fnAjaxParameters: _fnAjaxParameters, + _fnAjaxUpdateDraw: _fnAjaxUpdateDraw, + _fnAjaxDataSrc: _fnAjaxDataSrc, + _fnAddColumn: _fnAddColumn, + _fnColumnOptions: _fnColumnOptions, + _fnAdjustColumnSizing: _fnAdjustColumnSizing, + _fnVisibleToColumnIndex: _fnVisibleToColumnIndex, + _fnColumnIndexToVisible: _fnColumnIndexToVisible, + _fnVisbleColumns: _fnVisbleColumns, + _fnGetColumns: _fnGetColumns, + _fnColumnTypes: _fnColumnTypes, + _fnApplyColumnDefs: _fnApplyColumnDefs, + _fnHungarianMap: _fnHungarianMap, + _fnCamelToHungarian: _fnCamelToHungarian, + _fnLanguageCompat: _fnLanguageCompat, + _fnBrowserDetect: _fnBrowserDetect, + _fnAddData: _fnAddData, + _fnAddTr: _fnAddTr, + _fnNodeToDataIndex: _fnNodeToDataIndex, + _fnNodeToColumnIndex: _fnNodeToColumnIndex, + _fnGetCellData: _fnGetCellData, + _fnSetCellData: _fnSetCellData, + _fnSplitObjNotation: _fnSplitObjNotation, + _fnGetObjectDataFn: _fnGetObjectDataFn, + _fnSetObjectDataFn: _fnSetObjectDataFn, + _fnGetDataMaster: _fnGetDataMaster, + _fnClearTable: _fnClearTable, + _fnDeleteIndex: _fnDeleteIndex, + _fnInvalidate: _fnInvalidate, + _fnGetRowElements: _fnGetRowElements, + _fnCreateTr: _fnCreateTr, + _fnBuildHead: _fnBuildHead, + _fnDrawHead: _fnDrawHead, + _fnDraw: _fnDraw, + _fnReDraw: _fnReDraw, + _fnAddOptionsHtml: _fnAddOptionsHtml, + _fnDetectHeader: _fnDetectHeader, + _fnGetUniqueThs: _fnGetUniqueThs, + _fnFeatureHtmlFilter: _fnFeatureHtmlFilter, + _fnFilterComplete: _fnFilterComplete, + _fnFilterCustom: _fnFilterCustom, + _fnFilterColumn: _fnFilterColumn, + _fnFilter: _fnFilter, + _fnFilterCreateSearch: _fnFilterCreateSearch, + _fnEscapeRegex: _fnEscapeRegex, + _fnFilterData: _fnFilterData, + _fnFeatureHtmlInfo: _fnFeatureHtmlInfo, + _fnUpdateInfo: _fnUpdateInfo, + _fnInfoMacros: _fnInfoMacros, + _fnInitialise: _fnInitialise, + _fnInitComplete: _fnInitComplete, + _fnLengthChange: _fnLengthChange, + _fnFeatureHtmlLength: _fnFeatureHtmlLength, + _fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate, + _fnPageChange: _fnPageChange, + _fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing, + _fnProcessingDisplay: _fnProcessingDisplay, + _fnFeatureHtmlTable: _fnFeatureHtmlTable, + _fnScrollDraw: _fnScrollDraw, + _fnApplyToChildren: _fnApplyToChildren, + _fnCalculateColumnWidths: _fnCalculateColumnWidths, + _fnThrottle: _fnThrottle, + _fnConvertToWidth: _fnConvertToWidth, + _fnGetWidestNode: _fnGetWidestNode, + _fnGetMaxLenString: _fnGetMaxLenString, + _fnStringToCss: _fnStringToCss, + _fnSortFlatten: _fnSortFlatten, + _fnSort: _fnSort, + _fnSortAria: _fnSortAria, + _fnSortListener: _fnSortListener, + _fnSortAttachListener: _fnSortAttachListener, + _fnSortingClasses: _fnSortingClasses, + _fnSortData: _fnSortData, + _fnSaveState: _fnSaveState, + _fnLoadState: _fnLoadState, + _fnSettingsFromNode: _fnSettingsFromNode, + _fnLog: _fnLog, + _fnMap: _fnMap, + _fnBindAction: _fnBindAction, + _fnCallbackReg: _fnCallbackReg, + _fnCallbackFire: _fnCallbackFire, + _fnLengthOverflow: _fnLengthOverflow, + _fnRenderer: _fnRenderer, + _fnDataSource: _fnDataSource, + _fnRowAttributes: _fnRowAttributes, + _fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant + // in 1.10, so this dead-end function is + // added to prevent errors + } ); + + + // jQuery access + $.fn.dataTable = DataTable; + + // Provide access to the host jQuery object (circular reference) + DataTable.$ = $; + + // Legacy aliases + $.fn.dataTableSettings = DataTable.settings; + $.fn.dataTableExt = DataTable.ext; + + // With a capital `D` we return a DataTables API instance rather than a + // jQuery object + $.fn.DataTable = function ( opts ) { + return $(this).dataTable( opts ).api(); + }; + + // All properties that are available to $.fn.dataTable should also be + // available on $.fn.DataTable + $.each( DataTable, function ( prop, val ) { + $.fn.DataTable[ prop ] = val; + } ); + + + // Information about events fired by DataTables - for documentation. + /** + * Draw event, fired whenever the table is redrawn on the page, at the same + * point as fnDrawCallback. This may be useful for binding events or + * performing calculations when the table is altered at all. + * @name DataTable#draw.dt + * @event + * @param {event} e jQuery event object + * @param {object} o DataTables settings object {@link DataTable.models.oSettings} + */ + + /** + * Search event, fired when the searching applied to the table (using the + * built-in global search, or column filters) is altered. + * @name DataTable#search.dt + * @event + * @param {event} e jQuery event object + * @param {object} o DataTables settings object {@link DataTable.models.oSettings} + */ + + /** + * Page change event, fired when the paging of the table is altered. + * @name DataTable#page.dt + * @event + * @param {event} e jQuery event object + * @param {object} o DataTables settings object {@link DataTable.models.oSettings} + */ + + /** + * Order event, fired when the ordering applied to the table is altered. + * @name DataTable#order.dt + * @event + * @param {event} e jQuery event object + * @param {object} o DataTables settings object {@link DataTable.models.oSettings} + */ + + /** + * DataTables initialisation complete event, fired when the table is fully + * drawn, including Ajax data loaded, if Ajax data is required. + * @name DataTable#init.dt + * @event + * @param {event} e jQuery event object + * @param {object} oSettings DataTables settings object + * @param {object} json The JSON object request from the server - only + * present if client-side Ajax sourced data is used + */ + + /** + * State save event, fired when the table has changed state a new state save + * is required. This event allows modification of the state saving object + * prior to actually doing the save, including addition or other state + * properties (for plug-ins) or modification of a DataTables core property. + * @name DataTable#stateSaveParams.dt + * @event + * @param {event} e jQuery event object + * @param {object} oSettings DataTables settings object + * @param {object} json The state information to be saved + */ + + /** + * State load event, fired when the table is loading state from the stored + * data, but prior to the settings object being modified by the saved state + * - allowing modification of the saved state is required or loading of + * state for a plug-in. + * @name DataTable#stateLoadParams.dt + * @event + * @param {event} e jQuery event object + * @param {object} oSettings DataTables settings object + * @param {object} json The saved state information + */ + + /** + * State loaded event, fired when state has been loaded from stored data and + * the settings object has been modified by the loaded data. + * @name DataTable#stateLoaded.dt + * @event + * @param {event} e jQuery event object + * @param {object} oSettings DataTables settings object + * @param {object} json The saved state information + */ + + /** + * Processing event, fired when DataTables is doing some kind of processing + * (be it, order, searcg or anything else). It can be used to indicate to + * the end user that there is something happening, or that something has + * finished. + * @name DataTable#processing.dt + * @event + * @param {event} e jQuery event object + * @param {object} oSettings DataTables settings object + * @param {boolean} bShow Flag for if DataTables is doing processing or not + */ + + /** + * Ajax (XHR) event, fired whenever an Ajax request is completed from a + * request to made to the server for new data. This event is called before + * DataTables processed the returned data, so it can also be used to pre- + * process the data returned from the server, if needed. + * + * Note that this trigger is called in `fnServerData`, if you override + * `fnServerData` and which to use this event, you need to trigger it in you + * success function. + * @name DataTable#xhr.dt + * @event + * @param {event} e jQuery event object + * @param {object} o DataTables settings object {@link DataTable.models.oSettings} + * @param {object} json JSON returned from the server + * + * @example + * // Use a custom property returned from the server in another DOM element + * $('#table').dataTable().on('xhr.dt', function (e, settings, json) { + * $('#status').html( json.status ); + * } ); + * + * @example + * // Pre-process the data returned from the server + * $('#table').dataTable().on('xhr.dt', function (e, settings, json) { + * for ( var i=0, ien=json.aaData.length ; i + + + + +Created by FontForge 20120731 at Thu Dec 4 09:51:48 2014 + By Adam Bradley +Created by Adam Bradley with FontForge 2.0 (http://fontforge.sf.net) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/plugins/ionicons/fonts/ionicons28b5.ttf b/public/plugins/ionicons/fonts/ionicons28b5.ttf new file mode 100755 index 0000000..c4e4632 Binary files /dev/null and b/public/plugins/ionicons/fonts/ionicons28b5.ttf differ diff --git a/public/plugins/ionicons/fonts/ionicons28b5.woff b/public/plugins/ionicons/fonts/ionicons28b5.woff new file mode 100755 index 0000000..5f3a14e Binary files /dev/null and b/public/plugins/ionicons/fonts/ionicons28b5.woff differ diff --git a/public/plugins/lobibox/css/lobibox.css b/public/plugins/lobibox/css/lobibox.css new file mode 100755 index 0000000..7e1943c --- /dev/null +++ b/public/plugins/lobibox/css/lobibox.css @@ -0,0 +1,1057 @@ +/* + Created on : Mar 19, 2014, 9:48:25 AM + Author : @arboshiki +*/ +/* + Created on : Sep 19, 2014, 1:47:13 PM + Author : @arboshiki +*/ +/* + Author : @arboshiki +*/ +@import url(https://fonts.googleapis.com/css?family=Open+Sans:600,700,400,300); +/* + Created on : Aug 11, 2014, 5:14:12 PM + Author : @arboshiki +*/ +.animated-super-fast { + -webkit-animation-duration: 0.3s; + animation-duration: 0.3s; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; +} +.animated-fast { + -webkit-animation-duration: 0.5s; + animation-duration: 0.5s; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; +} +.animated { + -webkit-animation-duration: 1s; + animation-duration: 1s; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; +} +.animated-slow { + -webkit-animation-duration: 1.3s; + animation-duration: 1.3s; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; +} +@-webkit-keyframes bounce { + 0%, + 20%, + 50%, + 80%, + 100% { + -webkit-transform: translateY(0); + transform: translateY(0); + } + 40% { + -webkit-transform: translateY(-30px); + transform: translateY(-30px); + } + 60% { + -webkit-transform: translateY(-15px); + transform: translateY(-15px); + } +} +@keyframes bounce { + 0%, + 20%, + 50%, + 80%, + 100% { + transform: translateY(0); + } + 40% { + transform: translateY(-30px); + } + 60% { + transform: translateY(-15px); + } +} +@-webkit-keyframes jumpUp { + 0% { + -webkit-transform: translate3d(0, calc(230%), 0) scale3d(0, 1, 1); + -webkit-animation-timing-function: ease-in; + } + 40% { + -webkit-transform: translate3d(0, 0, 0) scale3d(0.02, 1.1, 1); + -webkit-animation-timing-function: ease-out; + } + 70% { + -webkit-transform: translate3d(0, -40px, 0) scale3d(0.8, 1.1, 1); + } + 100% { + -webkit-transform: translate3d(0, 0, 0) scale3d(1, 1, 1); + } +} +@keyframes jumpUp { + 0% { + transform: translate3d(0, calc(230%), 0) scale3d(0, 1, 1); + animation-timing-function: ease-in; + } + 40% { + transform: translate3d(0, 0, 0) scale3d(0.02, 1.1, 1); + animation-timing-function: ease-out; + } + 70% { + transform: translate3d(0, -40px, 0) scale3d(0.8, 1.1, 1); + } + 100% { + transform: translate3d(0, 0, 0) scale3d(1, 1, 1); + } +} +@-webkit-keyframes expandOpen { + 0% { + -webkit-transform: scale(1.8); + } + 50% { + -webkit-transform: scale(0.95); + } + 80% { + -webkit-transform: scale(1.05); + } + 90% { + -webkit-transform: scale(0.98); + } + 100% { + -webkit-transform: scale(1); + } +} +@keyframes expandOpen { + 0% { + transform: scale(1.8); + } + 50% { + transform: scale(0.95); + } + 80% { + transform: scale(1.05); + } + 90% { + transform: scale(0.98); + } + 100% { + transform: scale(1); + } +} +@keyframes fadeInScale { + 0% { + transform: scale(0); + opacity: 0.0; + } + 100% { + transform: scale(1); + opacity: 1; + } +} +@-webkit-keyframes fadeInScale { + 0% { + -webkit-transform: scale(0); + opacity: 0.0; + } + 100% { + -webkit-transform: scale(1); + opacity: 1; + } +} +@-webkit-keyframes zoomIn { + 0% { + opacity: 0; + -webkit-transform: scale(0.3); + transform: scale(0.3); + } + 50% { + opacity: 1; + } +} +@keyframes zoomIn { + 0% { + opacity: 0; + -webkit-transform: scale(0.3); + -ms-transform: scale(0.3); + transform: scale(0.3); + } + 50% { + opacity: 1; + } +} +@-webkit-keyframes zoomOut { + 0% { + opacity: 1; + -webkit-transform: scale(1); + transform: scale(1); + } + 50% { + opacity: 0; + -webkit-transform: scale(0.3); + transform: scale(0.3); + } + 100% { + opacity: 0; + } +} +@keyframes zoomOut { + 0% { + opacity: 1; + -webkit-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } + 50% { + opacity: 0; + -webkit-transform: scale(0.3); + -ms-transform: scale(0.3); + transform: scale(0.3); + } + 100% { + opacity: 0; + } +} +@-webkit-keyframes fadeInDown { + from { + opacity: 0; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + } + to { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} +@keyframes fadeInDown { + from { + opacity: 0; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + } + to { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} +.fadeInDown { + -webkit-animation-name: fadeInDown; + animation-name: fadeInDown; +} +.zoomIn { + -webkit-animation-name: zoomIn; + animation-name: zoomIn; +} +.zoomOut { + -webkit-animation-name: zoomOut; + animation-name: zoomOut; +} +.bounce { + -webkit-animation-name: bounce; + animation-name: bounce; +} +.jumpUp { + -webkit-animation-name: jumpUp; + animation-name: jumpUp; +} +.expandOpen { + animation-name: expandOpen; + -webkit-animation-name: expandOpen; +} +.fadeInScale { + animation-name: fadeInScale; + -webkit-animation-name: fadeInScale; +} +/* + Created on : Sep 19, 2014, 1:47:04 PM + Author : @arboshiki +*/ +body.lobibox-open { + overflow: hidden; +} +.lobibox { + position: fixed; + z-index: 4001; + font-family: 'Open Sans', Arial, Helvetica, sans-serif; + -webkit-box-shadow: 0 0 20px 5px rgba(0, 0, 0, 0.5); + box-shadow: 0 0 20px 5px rgba(0, 0, 0, 0.5); +} +.lobibox * { + box-sizing: border-box; + -webkit-box-sizing: border-box; +} +.lobibox .lobibox-header { + font-size: 20px; + padding: 5px 10px; + color: #eeeeee; +} +.lobibox .lobibox-header .btn-close { + float: right; + background-color: transparent; + cursor: pointer; + border: none; + outline: 0; + -webkit-transition: all 0.3s; + -o-transition: all 0.3s; + transition: all 0.3s; +} +.lobibox .lobibox-header .btn-close:hover { + text-shadow: 2px 2px 3px rgba(0, 0, 0, 0.7); +} +.lobibox .lobibox-body { + overflow: hidden; + display: table; + position: relative; + width: 100%; + padding: 15px 20px; + background-color: rgba(255, 255, 255, 0.98); + font-size: 16px; +} +.lobibox .lobibox-body .lobibox-icon-wrapper { + position: relative; + height: 100%; + display: table; + font-size: 60px; +} +.lobibox .lobibox-body .lobibox-icon-wrapper .lobibox-icon { + display: table-cell; + vertical-align: middle; +} +.lobibox .lobibox-body .lobibox-body-text-wrapper { + display: table-cell; + vertical-align: middle; + width: 100%; + padding-left: 10px; +} +.lobibox .lobibox-footer { + text-align: center; + padding: 6px; +} +.lobibox .lobibox-footer > * { + margin: 0 10px 0 0; +} +.lobibox .lobibox-footer.text-center { + text-align: center; +} +.lobibox .lobibox-footer.text-left { + text-align: left; +} +.lobibox .lobibox-footer.text-right { + text-align: right; +} +.lobibox.lobibox-confirm { + border: none; +} +.lobibox.lobibox-confirm .lobibox-header { + color: #eeeeee; + background-color: #3C2D2D; +} +.lobibox.lobibox-confirm .lobibox-body .lobibox-icon { + color: #3C2D2D; +} +.lobibox.lobibox-confirm .lobibox-footer { + background-color: #594343; +} +.lobibox.lobibox-success { + border: 1px solid #29B87E; +} +.lobibox.lobibox-success .lobibox-header { + color: #eeeeee; + background-color: #29B87E; +} +.lobibox.lobibox-success .lobibox-body .lobibox-icon { + color: #29B87E; +} +.lobibox.lobibox-success .lobibox-footer { + background-color: #40d498; +} +.lobibox.lobibox-error { + border: 1px solid #CA2121; +} +.lobibox.lobibox-error .lobibox-header { + color: #eeeeee; + background-color: #CA2121; +} +.lobibox.lobibox-error .lobibox-body .lobibox-icon { + color: #CA2121; +} +.lobibox.lobibox-error .lobibox-footer { + background-color: #e03e3e; +} +.lobibox.lobibox-info { + border: 1px solid #2E79B4; +} +.lobibox.lobibox-info .lobibox-header { + color: #eeeeee; + background-color: #2E79B4; +} +.lobibox.lobibox-info .lobibox-body .lobibox-icon { + color: #2E79B4; +} +.lobibox.lobibox-info .lobibox-footer { + background-color: #4593d0; +} +.lobibox.lobibox-warning { + border: 1px solid #CE812E; +} +.lobibox.lobibox-warning .lobibox-header { + color: #eeeeee; + background-color: #CE812E; +} +.lobibox.lobibox-warning .lobibox-body .lobibox-icon { + color: #CE812E; +} +.lobibox.lobibox-warning .lobibox-footer { + background-color: #d99a56; +} +.lobibox.lobibox-prompt { + border: none; +} +.lobibox.lobibox-prompt .lobibox-header { + color: #eeeeee; + background-color: #3c2d2d; +} +.lobibox.lobibox-prompt .lobibox-body { + padding: 20px; +} +.lobibox.lobibox-prompt .lobibox-body .lobibox-input { + min-height: 38px; + border: 1px solid #21cb91; + width: 100%; + padding: 5px; + font-size: 18px; + outline: 0; +} +.lobibox.lobibox-prompt .lobibox-body .lobibox-input:focus { + background-color: #EEE; +} +.lobibox.lobibox-prompt .lobibox-body .lobibox-input.invalid { + border-color: #DC2B2A; +} +.lobibox.lobibox-prompt .lobibox-body .lobibox-input-error-message { + margin-top: 5px; + margin-bottom: 0; + font-size: 13px; + color: #DC2B2A; +} +.lobibox.lobibox-prompt .lobibox-footer { + background-color: #594343; +} +.lobibox.lobibox-progress .lobibox-header { + background-color: #2F5D6D; +} +.lobibox.lobibox-progress .lobibox-body { + padding: 15px; + font-size: 16px; +} +.lobibox.lobibox-progress .lobibox-body .lobibox-progress-bar-wrapper { + position: relative; + height: 20px; + border: 1px solid #c3c3c3; + border-radius: 10px; + background-color: #d5d5d5; +} +.lobibox.lobibox-progress .lobibox-body .lobibox-progress-bar-wrapper .lobibox-progress-bar { + width: 0; + border-radius: 10px; + background-color: #468ba2; + height: 100%; + text-align: center; +} +.lobibox.lobibox-progress .lobibox-body .lobibox-progress-bar-wrapper .lobibox-progress-text { + position: absolute; + text-align: center; + top: 0; + width: 100%; +} +.lobibox.lobibox-progress .lobibox-body .lobibox-progress-outer { + margin-bottom: 0; +} +.lobibox.lobibox-progress .lobibox-body .lobibox-progress-outer .progress-bar { + transition: none; +} +.lobibox.lobibox-progress .lobibox-body .lobibox-progress-outer [data-role="progress-text"] { + font-weight: bold; + color: rgba(0, 0, 0, 0.7); +} +.lobibox.lobibox-window { + border: 3px solid #225EB8; + border-radius: 6px; +} +.lobibox.lobibox-window .lobibox-header { + background-color: #225EB8; + color: #eeeeee; + font-size: 18px; +} +.lobibox.lobibox-window .lobibox-body { + overflow: auto; + display: block; + font-size: 14px; + padding: 15px; + background-color: #f5f8fd; +} +.lobibox.lobibox-window .lobibox-footer { + background-color: #8ab0e9; +} +.lobibox.lobibox-window :last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.lobibox.draggable .lobibox-header { + cursor: move; +} +.lobibox .lobibox-btn { + display: inline-block; + padding: 8px 14px; + font-size: 14px; + cursor: pointer; + border: 1px solid transparent; + border-radius: 2px; + line-height: initial; +} +.lobibox .lobibox-btn.lobibox-btn-cancel { + color: #FFF; + background-color: #CA2121; + border-color: #CA2121; +} +.lobibox .lobibox-btn.lobibox-btn-cancel:hover, +.lobibox .lobibox-btn.lobibox-btn-cancel:focus, +.lobibox .lobibox-btn.lobibox-btn-cancel.focus, +.lobibox .lobibox-btn.lobibox-btn-cancel:active, +.lobibox .lobibox-btn.lobibox-btn-cancel.active, +.open > .dropdown-toggle.lobibox .lobibox-btn.lobibox-btn-cancel { + color: #FFF; + background-color: #9e1a1a; + border-color: #951818; +} +.lobibox .lobibox-btn.lobibox-btn-cancel:active, +.lobibox .lobibox-btn.lobibox-btn-cancel.active, +.open > .dropdown-toggle.lobibox .lobibox-btn.lobibox-btn-cancel { + background-image: none; +} +.lobibox .lobibox-btn.lobibox-btn-cancel.disabled, +.lobibox .lobibox-btn.lobibox-btn-cancel[disabled], +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-cancel, +.lobibox .lobibox-btn.lobibox-btn-cancel.disabled:hover, +.lobibox .lobibox-btn.lobibox-btn-cancel[disabled]:hover, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-cancel:hover, +.lobibox .lobibox-btn.lobibox-btn-cancel.disabled:focus, +.lobibox .lobibox-btn.lobibox-btn-cancel[disabled]:focus, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-cancel:focus, +.lobibox .lobibox-btn.lobibox-btn-cancel.disabled.focus, +.lobibox .lobibox-btn.lobibox-btn-cancel[disabled].focus, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-cancel.focus, +.lobibox .lobibox-btn.lobibox-btn-cancel.disabled:active, +.lobibox .lobibox-btn.lobibox-btn-cancel[disabled]:active, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-cancel:active, +.lobibox .lobibox-btn.lobibox-btn-cancel.disabled.active, +.lobibox .lobibox-btn.lobibox-btn-cancel[disabled].active, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-cancel.active { + background-color: #CA2121; + border-color: #CA2121; +} +.lobibox .lobibox-btn.lobibox-btn-cancel .badge { + color: #CA2121; + background-color: #FFF; +} +.lobibox .lobibox-btn.lobibox-btn-yes { + color: #FFF; + background-color: #29B87E; + border-color: #29B87E; +} +.lobibox .lobibox-btn.lobibox-btn-yes:hover, +.lobibox .lobibox-btn.lobibox-btn-yes:focus, +.lobibox .lobibox-btn.lobibox-btn-yes.focus, +.lobibox .lobibox-btn.lobibox-btn-yes:active, +.lobibox .lobibox-btn.lobibox-btn-yes.active, +.open > .dropdown-toggle.lobibox .lobibox-btn.lobibox-btn-yes { + color: #FFF; + background-color: #208e61; + border-color: #1e865c; +} +.lobibox .lobibox-btn.lobibox-btn-yes:active, +.lobibox .lobibox-btn.lobibox-btn-yes.active, +.open > .dropdown-toggle.lobibox .lobibox-btn.lobibox-btn-yes { + background-image: none; +} +.lobibox .lobibox-btn.lobibox-btn-yes.disabled, +.lobibox .lobibox-btn.lobibox-btn-yes[disabled], +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-yes, +.lobibox .lobibox-btn.lobibox-btn-yes.disabled:hover, +.lobibox .lobibox-btn.lobibox-btn-yes[disabled]:hover, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-yes:hover, +.lobibox .lobibox-btn.lobibox-btn-yes.disabled:focus, +.lobibox .lobibox-btn.lobibox-btn-yes[disabled]:focus, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-yes:focus, +.lobibox .lobibox-btn.lobibox-btn-yes.disabled.focus, +.lobibox .lobibox-btn.lobibox-btn-yes[disabled].focus, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-yes.focus, +.lobibox .lobibox-btn.lobibox-btn-yes.disabled:active, +.lobibox .lobibox-btn.lobibox-btn-yes[disabled]:active, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-yes:active, +.lobibox .lobibox-btn.lobibox-btn-yes.disabled.active, +.lobibox .lobibox-btn.lobibox-btn-yes[disabled].active, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-yes.active { + background-color: #29B87E; + border-color: #29B87E; +} +.lobibox .lobibox-btn.lobibox-btn-yes .badge { + color: #29B87E; + background-color: #FFF; +} +.lobibox .lobibox-btn.lobibox-btn-no { + color: #FFF; + background-color: #0760B3; + border-color: #0760B3; +} +.lobibox .lobibox-btn.lobibox-btn-no:hover, +.lobibox .lobibox-btn.lobibox-btn-no:focus, +.lobibox .lobibox-btn.lobibox-btn-no.focus, +.lobibox .lobibox-btn.lobibox-btn-no:active, +.lobibox .lobibox-btn.lobibox-btn-no.active, +.open > .dropdown-toggle.lobibox .lobibox-btn.lobibox-btn-no { + color: #FFF; + background-color: #054682; + border-color: #054078; +} +.lobibox .lobibox-btn.lobibox-btn-no:active, +.lobibox .lobibox-btn.lobibox-btn-no.active, +.open > .dropdown-toggle.lobibox .lobibox-btn.lobibox-btn-no { + background-image: none; +} +.lobibox .lobibox-btn.lobibox-btn-no.disabled, +.lobibox .lobibox-btn.lobibox-btn-no[disabled], +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-no, +.lobibox .lobibox-btn.lobibox-btn-no.disabled:hover, +.lobibox .lobibox-btn.lobibox-btn-no[disabled]:hover, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-no:hover, +.lobibox .lobibox-btn.lobibox-btn-no.disabled:focus, +.lobibox .lobibox-btn.lobibox-btn-no[disabled]:focus, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-no:focus, +.lobibox .lobibox-btn.lobibox-btn-no.disabled.focus, +.lobibox .lobibox-btn.lobibox-btn-no[disabled].focus, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-no.focus, +.lobibox .lobibox-btn.lobibox-btn-no.disabled:active, +.lobibox .lobibox-btn.lobibox-btn-no[disabled]:active, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-no:active, +.lobibox .lobibox-btn.lobibox-btn-no.disabled.active, +.lobibox .lobibox-btn.lobibox-btn-no[disabled].active, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-no.active { + background-color: #0760B3; + border-color: #0760B3; +} +.lobibox .lobibox-btn.lobibox-btn-no .badge { + color: #0760B3; + background-color: #FFF; +} +.lobibox .lobibox-btn.lobibox-btn-ok { + color: #FFF; + background-color: #0760B3; + border-color: #0760B3; +} +.lobibox .lobibox-btn.lobibox-btn-ok:hover, +.lobibox .lobibox-btn.lobibox-btn-ok:focus, +.lobibox .lobibox-btn.lobibox-btn-ok.focus, +.lobibox .lobibox-btn.lobibox-btn-ok:active, +.lobibox .lobibox-btn.lobibox-btn-ok.active, +.open > .dropdown-toggle.lobibox .lobibox-btn.lobibox-btn-ok { + color: #FFF; + background-color: #054682; + border-color: #054078; +} +.lobibox .lobibox-btn.lobibox-btn-ok:active, +.lobibox .lobibox-btn.lobibox-btn-ok.active, +.open > .dropdown-toggle.lobibox .lobibox-btn.lobibox-btn-ok { + background-image: none; +} +.lobibox .lobibox-btn.lobibox-btn-ok.disabled, +.lobibox .lobibox-btn.lobibox-btn-ok[disabled], +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-ok, +.lobibox .lobibox-btn.lobibox-btn-ok.disabled:hover, +.lobibox .lobibox-btn.lobibox-btn-ok[disabled]:hover, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-ok:hover, +.lobibox .lobibox-btn.lobibox-btn-ok.disabled:focus, +.lobibox .lobibox-btn.lobibox-btn-ok[disabled]:focus, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-ok:focus, +.lobibox .lobibox-btn.lobibox-btn-ok.disabled.focus, +.lobibox .lobibox-btn.lobibox-btn-ok[disabled].focus, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-ok.focus, +.lobibox .lobibox-btn.lobibox-btn-ok.disabled:active, +.lobibox .lobibox-btn.lobibox-btn-ok[disabled]:active, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-ok:active, +.lobibox .lobibox-btn.lobibox-btn-ok.disabled.active, +.lobibox .lobibox-btn.lobibox-btn-ok[disabled].active, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-ok.active { + background-color: #0760B3; + border-color: #0760B3; +} +.lobibox .lobibox-btn.lobibox-btn-ok .badge { + color: #0760B3; + background-color: #FFF; +} +.lobibox .lobibox-btn.lobibox-btn-default { + color: #000; + background-color: #e2e2e2; + border-color: #dadada; +} +.lobibox .lobibox-btn.lobibox-btn-default:hover, +.lobibox .lobibox-btn.lobibox-btn-default:focus, +.lobibox .lobibox-btn.lobibox-btn-default.focus, +.lobibox .lobibox-btn.lobibox-btn-default:active, +.lobibox .lobibox-btn.lobibox-btn-default.active, +.open > .dropdown-toggle.lobibox .lobibox-btn.lobibox-btn-default { + color: #000; + background-color: #c9c9c9; + border-color: #bcbcbc; +} +.lobibox .lobibox-btn.lobibox-btn-default:active, +.lobibox .lobibox-btn.lobibox-btn-default.active, +.open > .dropdown-toggle.lobibox .lobibox-btn.lobibox-btn-default { + background-image: none; +} +.lobibox .lobibox-btn.lobibox-btn-default.disabled, +.lobibox .lobibox-btn.lobibox-btn-default[disabled], +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-default, +.lobibox .lobibox-btn.lobibox-btn-default.disabled:hover, +.lobibox .lobibox-btn.lobibox-btn-default[disabled]:hover, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-default:hover, +.lobibox .lobibox-btn.lobibox-btn-default.disabled:focus, +.lobibox .lobibox-btn.lobibox-btn-default[disabled]:focus, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-default:focus, +.lobibox .lobibox-btn.lobibox-btn-default.disabled.focus, +.lobibox .lobibox-btn.lobibox-btn-default[disabled].focus, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-default.focus, +.lobibox .lobibox-btn.lobibox-btn-default.disabled:active, +.lobibox .lobibox-btn.lobibox-btn-default[disabled]:active, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-default:active, +.lobibox .lobibox-btn.lobibox-btn-default.disabled.active, +.lobibox .lobibox-btn.lobibox-btn-default[disabled].active, +fieldset[disabled] .lobibox .lobibox-btn.lobibox-btn-default.active { + background-color: #e2e2e2; + border-color: #dadada; +} +.lobibox .lobibox-btn.lobibox-btn-default .badge { + color: #e2e2e2; + background-color: #000; +} +.lobibox.lobibox-hidden { + display: none; +} +.lobibox-backdrop { + position: fixed; + z-index: 4000; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); +} +/* + Created on : Sep 19, 2014, 2:01:43 PM + Author : @arboshiki +*/ +.lobibox-notify-wrapper { + z-index: 5000; + position: fixed; +} +.lobibox-notify-wrapper.top { + top: 0px; +} +.lobibox-notify-wrapper.bottom { + bottom: 0px; +} +.lobibox-notify-wrapper.left { + left: 0px; + margin-right: 0px; +} +.lobibox-notify-wrapper.right { + right: 0px; + margin-left: 0px; +} +.lobibox-notify-wrapper.right .lobibox-notify { + margin-left: auto; +} +.lobibox-notify-wrapper.center { + left: 50%; +} +.lobibox-notify-wrapper-large { + z-index: 5000; + position: fixed; +} +.lobibox-notify-wrapper-large.top { + top: 0px; +} +.lobibox-notify-wrapper-large.bottom { + bottom: 0px; +} +.lobibox-notify-wrapper-large.left { + left: 0px; +} +.lobibox-notify-wrapper-large.left .lb-notify-tabs > li { + float: left; + margin-left: 0; + margin-right: 2px; +} +.lobibox-notify-wrapper-large.right { + right: 0px; +} +.lobibox-notify-wrapper-large .lb-notify-tabs { + list-style: none; + padding: 0; + margin: 0 0 -5px 0; +} +.lobibox-notify-wrapper-large .lb-notify-tabs > li { + float: right; + margin-left: 2px; +} +.lobibox-notify-wrapper-large .lb-notify-tabs > li > a { + text-align: center; + display: table; + text-decoration: none; + font-size: 18px; + height: 32px; + color: #FFF; + width: 28px; + opacity: 0.6; +} +.lobibox-notify-wrapper-large .lb-notify-tabs > li > a:hover, +.lobibox-notify-wrapper-large .lb-notify-tabs > li > a:active, +.lobibox-notify-wrapper-large .lb-notify-tabs > li > a:focus, +.lobibox-notify-wrapper-large .lb-notify-tabs > li > a:hover:active { + color: #FFF; +} +.lobibox-notify-wrapper-large .lb-notify-tabs > li > a .tab-control-icon { + display: table-cell; + vertical-align: middle; +} +.lobibox-notify-wrapper-large .lb-notify-tabs > li.lobibox-notify-default > a { + background-color: rgba(28, 28, 28, 0.9); + border-color: #141414; +} +.lobibox-notify-wrapper-large .lb-notify-tabs > li.lobibox-notify-default > a:hover { + background-color: #1c1c1c; + border-color: #0f0f0f; +} +.lobibox-notify-wrapper-large .lb-notify-tabs > li.lobibox-notify-error > a { + background-color: rgba(202, 33, 33, 0.9); + border-color: #bd1f1f; +} +.lobibox-notify-wrapper-large .lb-notify-tabs > li.lobibox-notify-error > a:hover { + background-color: #CA2121; + border-color: #b41d1d; +} +.lobibox-notify-wrapper-large .lb-notify-tabs > li.lobibox-notify-success > a { + background-color: rgba(41, 184, 126, 0.9); + border-color: #26ab75; +} +.lobibox-notify-wrapper-large .lb-notify-tabs > li.lobibox-notify-success > a:hover { + background-color: #29B87E; + border-color: #24a370; +} +.lobibox-notify-wrapper-large .lb-notify-tabs > li.lobibox-notify-warning > a { + background-color: rgba(206, 129, 46, 0.9); + border-color: #c1792b; +} +.lobibox-notify-wrapper-large .lb-notify-tabs > li.lobibox-notify-warning > a:hover { + background-color: #CE812E; + border-color: #b97429; +} +.lobibox-notify-wrapper-large .lb-notify-tabs > li.lobibox-notify-info > a { + background-color: rgba(46, 121, 180, 0.9); + border-color: #2b71a8; +} +.lobibox-notify-wrapper-large .lb-notify-tabs > li.lobibox-notify-info > a:hover { + background-color: #2E79B4; + border-color: #296ba0; +} +.lobibox-notify-wrapper-large .lb-notify-tabs > li.active > a { + opacity: 1; +} +.lobibox-notify-wrapper-large .lb-notify-tabs:after { + content: ""; + display: block; + clear: both; +} +.lobibox-notify-wrapper-large .lb-notify-wrapper { + background-color: transparent; + padding: 0; + border: none; +} +.lobibox-notify-wrapper-large .lb-notify-wrapper .lb-tab-pane { + display: none; +} +.lobibox-notify-wrapper-large .lb-notify-wrapper .lb-tab-pane.active { + display: block; +} +.lobibox-notify-wrapper-large .lb-notify-wrapper .lobibox-notify { + min-height: 150px; +} +.lobibox-notify-wrapper-large .lb-notify-wrapper .lobibox-notify .lobibox-notify-icon-wrapper { + width: 100px; +} +.lobibox-notify-wrapper-large .lb-notify-wrapper .lobibox-notify .lobibox-notify-icon > div .icon-el { + font-size: 78px; +} +.lobibox-notify-wrapper-large .lb-notify-wrapper .lobibox-notify .lobibox-notify-body { + margin: 13px 20px; + margin-left: 130px; +} +.lobibox-notify { + position: relative; + min-height: 85px; + font-family: 'Open Sans', Arial, Helvetica, sans-serif; + font-size: 14px; + margin: 7px 0; + border-radius: 0; + border: 1px solid transparent; + + -webkit-transition: all 0.2s; + -o-transition: all 0.2s; + transition: all 0.2s; +} +.lobibox-notify .lobibox-notify-icon-wrapper { + position: absolute; + left: 15px; + width: 60px; + height: 100%; +} +.lobibox-notify .lobibox-notify-icon { + display: table; + width: 100%; + height: 100%; +} +.lobibox-notify .lobibox-notify-icon > div { + display: table-cell; + vertical-align: middle; +} +.lobibox-notify .lobibox-notify-icon > div > img { + width: 100%; + max-width: 100%; + margin-top: 3px; + border-radius: 4px; +} +.lobibox-notify .lobibox-notify-icon > div .icon-el { + text-align: center; + font-size: 3em; + padding-top:10px; +} +.lobibox-notify .lobibox-notify-body { + margin: 10px 20px; + margin-left: 90px; +} +.lobibox-notify .lobibox-notify-title { + font-size: 20px; +} +.lobibox-notify .lobibox-notify-msg { + overflow: hidden; +} +.lobibox-notify .lobibox-close { + position: absolute; + text-align: center; + border-radius: 50%; + right: 10px; + top: 10px; + font-size: 20px; + line-height: 19px; + width: 19px; + height: 19px; + -webkit-transition: all 0.2s; + -o-transition: all 0.2s; + transition: all 0.2s; +} +.lobibox-notify .lobibox-close:hover { + background-color: rgba(0, 0, 0, 0.5); + font-weight: bold; +} +.lobibox-notify .lobibox-delay-indicator { + position: absolute; + left: 0; + right: 0; + bottom: 0; + height: 3px; +} +.lobibox-notify .lobibox-delay-indicator > div { + position: relative; + height: 100%; + width: 0; + background-color: #e8e8e8; +} +.lobibox-notify.lobibox-notify-default { + border-color: #0f0f0f; + background-color: #1c1c1c; + color: #FFF; +} +.lobibox-notify.lobibox-notify-default:hover { + background-color: #1c1c1c; + border-color: #FFF; +} +.lobibox-notify.lobibox-notify-default .lobibox-close:hover { + background-color: #4f4f4f; +} +.lobibox-notify.lobibox-notify-error { + border-color: #b41d1d; + background-color: #CA2121; + color: #FFF; +} +.lobibox-notify.lobibox-notify-error:hover { + background-color: #CA2121; + border-color: #FFF; +} +.lobibox-notify.lobibox-notify-success { + border-color: #24a370; + background-color: #29B87E; + color: #FFF; +} +.lobibox-notify.lobibox-notify-success:hover { + background-color: #29B87E; + border-color: #FFF; +} +.lobibox-notify.lobibox-notify-warning { + border-color: #b97429; + background-color: #CE812E; + color: #FFF; +} +.lobibox-notify.lobibox-notify-warning:hover { + background-color: #CE812E; + border-color: #FFF; +} +.lobibox-notify.lobibox-notify-info { + border-color: #296ba0; + background-color: #2E79B4; + color: #FFF; +} +.lobibox-notify.lobibox-notify-info:hover { + background-color: #2E79B4; + border-color: #FFF; +} +.lobibox-notify.rounded { + border-radius: 30px; +} +.lobibox-notify:hover { + cursor: pointer; + +} +.lobibox-notify.notify-mini { + min-height: 36px; +} +.lobibox-notify.notify-mini .lobibox-notify-title { + margin-top: -5px; + font-size: 20px; + line-height: 22px; +} +.lobibox-notify.notify-mini .lobibox-notify-msg { + line-height: 16px; +} +.lobibox-notify.notify-mini .lobibox-notify-icon-wrapper { + left: 12px; + width: 32px; +} +.lobibox-notify.notify-mini .lobibox-notify-icon > div .icon-el { + font-size: 32px; +} +.lobibox-notify.notify-mini .lobibox-notify-body { + margin: 15px 30px 15px 56px; +} +.lobibox-notify.without-icon .lobibox-notify-body { + margin-left: 20px; +} diff --git a/public/plugins/lobibox/dist/js/lobibox.min.js b/public/plugins/lobibox/dist/js/lobibox.min.js new file mode 100755 index 0000000..4f1f0e0 --- /dev/null +++ b/public/plugins/lobibox/dist/js/lobibox.min.js @@ -0,0 +1 @@ +var Lobibox=Lobibox||{};!function(){function LobiboxPrompt(type,options){this.$input=null,this.$type="prompt",this.$promptType=type,options=$.extend({},Lobibox.prompt.DEFAULT_OPTIONS,options),this.$options=this._processInput(options),this._init(),this.debug(this)}function LobiboxConfirm(options){this.$type="confirm",this.$options=this._processInput(options),this._init(),this.debug(this)}function LobiboxAlert(type,options){this.$type=type,this.$options=this._processInput(options),this._init(),this.debug(this)}function LobiboxProgress(options){this.$type="progress",this.$progressBarElement=null,this.$options=this._processInput(options),this.$progress=0,this._init(),this.debug(this)}function LobiboxWindow(type,options){this.$type=type,this.$options=this._processInput(options),this._init(),this.debug(this)}Lobibox.counter=0,Lobibox.prompt=function(type,options){return new LobiboxPrompt(type,options)},Lobibox.confirm=function(options){return new LobiboxConfirm(options)},Lobibox.progress=function(options){return new LobiboxProgress(options)},Lobibox.error={},Lobibox.success={},Lobibox.warning={},Lobibox.info={},Lobibox.alert=function(type,options){return["success","error","warning","info"].indexOf(type)>-1?new LobiboxAlert(type,options):void 0},Lobibox.window=function(options){return new LobiboxWindow("window",options)};var LobiboxBase={$type:null,$el:null,$options:null,debug:function(){this.$options.debug&&window.console.debug.apply(window.console,arguments)},_processInput:function(options){if($.isArray(options.buttons)){for(var btns={},i=0;i").addClass(op["class"]).attr("data-type",type).html(op.text);return me.$options.callback&&"function"==typeof me.$options.callback&&btn.on("click.lobibox",function(ev){var bt=$(this);me._onButtonClick(me.$options.buttons[type],type),me.$options.callback(me,bt.data("type"),ev)}),btn.click(function(){me._onButtonClick(me.$options.buttons[type],type)}),btn},_onButtonClick:function(buttonOptions,type){var me=this;("ok"===type&&"prompt"===me.$type&&me.isValid()||"prompt"!==me.$type||"ok"!==type)&&buttonOptions&&buttonOptions.closeOnClick&&me.destroy()},_generateButtons:function(){var me=this,btns=[];for(var i in me.$options.buttons)if(me.$options.buttons.hasOwnProperty(i)){var op=me.$options.buttons[i],btn=me._createButton(i,op);btns.push(btn)}return btns},_createMarkup:function(){var me=this,lobibox=$('
');lobibox.attr("data-is-modal",me.$options.modal);var header=$('
').append(''),body=$('
');if(lobibox.append(header),lobibox.append(body),me.$options.buttons&&!$.isEmptyObject(me.$options.buttons)){var footer=$('');footer.append(me._generateButtons()),lobibox.append(footer),Lobibox.base.OPTIONS.buttonsAlign.indexOf(me.$options.buttonsAlign)>-1&&footer.addClass("text-"+me.$options.buttonsAlign)}me.$el=lobibox.addClass(Lobibox.base.OPTIONS.modalClasses[me.$type])},_setSize:function(){var me=this;me.setWidth(me.$options.width),me.setHeight("auto"===me.$options.height?me.$el.outerHeight():me.$options.height)},_calculateBodyHeight:function(height){var me=this,headerHeight=me.$el.find(".lobibox-header").outerHeight(),footerHeight=me.$el.find(".lobibox-footer").outerHeight();return height-(headerHeight?headerHeight:0)-(footerHeight?footerHeight:0)},_addBackdrop:function(){0===$(".lobibox-backdrop").length&&$("body").append('
')},_triggerEvent:function(type){var me=this;me.$options[type]&&"function"==typeof me.$options[type]&&me.$options[type](me)},_calculateWidth:function(width){var me=this;return width=Math.min(Math.max(width,me.$options.width),$(window).outerWidth()),width===$(window).outerWidth()&&(width-=2*me.$options.horizontalOffset),width},_calculateHeight:function(height){var me=this;return console.log(me.$options.height),height=Math.min(Math.max(height,me.$options.height),$(window).outerHeight()),height===$(window).outerHeight()&&(height-=2*me.$options.verticalOffset),height},_addCloseButton:function(){var me=this,closeBtn=$('×');me.$el.find(".lobibox-header").append(closeBtn),closeBtn.on("mousedown",function(ev){ev.stopPropagation()}),closeBtn.on("click.lobibox",function(){me.destroy()})},_position:function(){var me=this;me._setSize();var pos=me._calculatePosition();me.setPosition(pos.left,pos.top)},_isMobileScreen:function(){return $(window).outerWidth()<768},_enableDrag:function(){var el=this.$el,heading=el.find(".lobibox-header");heading.on("mousedown.lobibox",function(ev){el.attr("offset-left",ev.offsetX),el.attr("offset-top",ev.offsetY),el.attr("allow-drag","true")}),$(document).on("mouseup.lobibox",function(){el.attr("allow-drag","false")}),$(document).on("mousemove.lobibox",function(ev){if("true"===el.attr("allow-drag")){var left=ev.clientX-parseInt(el.attr("offset-left"),10)-parseInt(el.css("border-left-width"),10),top=ev.clientY-parseInt(el.attr("offset-top"),10)-parseInt(el.css("border-top-width"),10);el.css({left:left,top:top})}})},_setContent:function(msg){var me=this;return me.$el.find(".lobibox-body").html(msg),me},_beforeShow:function(){var me=this;me._triggerEvent("onShow")},_afterShow:function(){var me=this;Lobibox.counter++,me.$el.attr("data-nth",Lobibox.counter),me.$options.draggable||$(window).on("resize.lobibox-"+me.$el.attr("data-nth"),function(){me.refreshWidth(),me.refreshHeight(),me.$el.css("left","50%").css("margin-left","-"+me.$el.width()/2+"px"),me.$el.css("top","50%").css("margin-top","-"+me.$el.height()/2+"px")}),me._triggerEvent("shown")},_beforeClose:function(){var me=this;me._triggerEvent("beforeClose")},_afterClose:function(){var me=this;me.$options.draggable||$(window).off("resize.lobibox-"+me.$el.attr("data-nth")),me._triggerEvent("closed")},hide:function(){function callback(){me.$el.addClass("lobibox-hidden"),0===$(".lobibox[data-is-modal=true]:not(.lobibox-hidden)").length&&($(".lobibox-backdrop").remove(),$("body").removeClass(Lobibox.base.OPTIONS.bodyClass))}var me=this;return me.$options.hideClass?(me.$el.removeClass(me.$options.showClass),me.$el.addClass(me.$options.hideClass),setTimeout(function(){callback()},me.$options.delayToRemove)):callback(),this},destroy:function(){function callback(){me.$el.remove(),0===$(".lobibox[data-is-modal=true]").length&&($(".lobibox-backdrop").remove(),$("body").removeClass(Lobibox.base.OPTIONS.bodyClass)),me._afterClose()}var me=this;return me._beforeClose(),me.$options.hideClass?(me.$el.removeClass(me.$options.showClass).addClass(me.$options.hideClass),setTimeout(function(){callback()},me.$options.delayToRemove)):callback(),this},setWidth:function(width){var me=this;return me.$el.css("width",me._calculateWidth(width)),me},refreshWidth:function(){this.setWidth(this.$el.width())},refreshHeight:function(){this.setHeight(this.$el.height())},setHeight:function(height){var me=this;return me.$el.css("height",me._calculateHeight(height)).find(".lobibox-body").css("height",me._calculateBodyHeight(me.$el.innerHeight())),me},setSize:function(width,height){var me=this;return me.setWidth(width),me.setHeight(height),me},setPosition:function(left,top){var pos;return"number"==typeof left&&"number"==typeof top?pos={left:left,top:top}:"string"==typeof left&&(pos=this._calculatePosition(left)),this.$el.css(pos),this},setTitle:function(title){return this.$el.find(".lobibox-title").html(title)},getTitle:function(){return this.$el.find(".lobibox-title").html()},show:function(){var me=this,$body=$("body");if(me._beforeShow(),me.$el.removeClass("lobibox-hidden"),$body.append(me.$el),me.$options.buttons){var buttons=me.$el.find(".lobibox-footer").children();buttons[0].focus()}return me.$options.modal&&($body.addClass(Lobibox.base.OPTIONS.bodyClass),me._addBackdrop()),me.$options.delay!==!1&&setTimeout(function(){me.destroy()},me.$options.delay),me._afterShow(),me}};Lobibox.base={},Lobibox.base.OPTIONS={bodyClass:"lobibox-open",modalClasses:{error:"lobibox-error",success:"lobibox-success",info:"lobibox-info",warning:"lobibox-warning",confirm:"lobibox-confirm",progress:"lobibox-progress",prompt:"lobibox-prompt","default":"lobibox-default",window:"lobibox-window"},buttonsAlign:["left","center","right"],buttons:{ok:{"class":"lobibox-btn lobibox-btn-default",text:"OK",closeOnClick:!0},cancel:{"class":"lobibox-btn lobibox-btn-cancel",text:"Cancel",closeOnClick:!0},yes:{"class":"lobibox-btn lobibox-btn-yes",text:"Yes",closeOnClick:!0},no:{"class":"lobibox-btn lobibox-btn-no",text:"No",closeOnClick:!0}},icons:{bootstrap:{confirm:"glyphicon glyphicon-question-sign",success:"glyphicon glyphicon-ok-sign",error:"glyphicon glyphicon-remove-sign",warning:"glyphicon glyphicon-exclamation-sign",info:"glyphicon glyphicon-info-sign"},fontAwesome:{confirm:"fa fa-question-circle",success:"fa fa-check-circle",error:"fa fa-times-circle",warning:"fa fa-exclamation-circle",info:"fa fa-info-circle"}}},Lobibox.base.DEFAULTS={horizontalOffset:5,verticalOffset:5,width:600,height:"auto",closeButton:!0,draggable:!1,customBtnClass:"lobibox-btn lobibox-btn-default",modal:!0,debug:!1,buttonsAlign:"center",closeOnEsc:!0,delayToRemove:200,delay:!1,baseClass:"animated-super-fast",showClass:"zoomIn",hideClass:"zoomOut",iconSource:"bootstrap",onShow:null,shown:null,beforeClose:null,closed:null},LobiboxPrompt.prototype=$.extend({},LobiboxBase,{constructor:LobiboxPrompt,_processInput:function(options){var me=this,mergedOptions=LobiboxBase._processInput.call(me,options);return mergedOptions.buttons={ok:Lobibox.base.OPTIONS.buttons.ok,cancel:Lobibox.base.OPTIONS.buttons.cancel},options=$.extend({},mergedOptions,LobiboxPrompt.DEFAULT_OPTIONS,options)},_init:function(){var me=this;LobiboxBase._init.call(me),me.show()},_afterShow:function(){var me=this;me._setContent(me._createInput())._position(),me.$input.focus(),LobiboxBase._afterShow.call(me)},_createInput:function(){var label,me=this;return me.$input=me.$options.multiline?$("").attr("rows",me.$options.lines):$(''),me.$input.addClass("lobibox-input").attr(me.$options.attrs),me.$options.value&&me.setValue(me.$options.value),me.$options.label&&(label=$("")),$("
").append(label,me.$input)},setValue:function(val){return this.$input.val(val),this},getValue:function(){return this.$input.val()},isValid:function(){var me=this,$error=me.$el.find(".lobibox-input-error-message");return me.$options.required&&!me.getValue()?(me.$input.addClass("invalid"),0===$error.length&&(me.$el.find(".lobibox-body").append('

'+me.$options.errorMessage+"

"),me._position(),me.$input.focus()),!1):(me.$input.removeClass("invalid"),$error.remove(),me._position(),me.$input.focus(),!0)}}),LobiboxPrompt.DEFAULT_OPTIONS={width:400,attrs:{},value:"",multiline:!1,lines:3,type:"text",label:"",required:!0,errorMessage:"The field is required"},LobiboxConfirm.prototype=$.extend({},LobiboxBase,{constructor:LobiboxConfirm,_processInput:function(options){var me=this,mergedOptions=LobiboxBase._processInput.call(me,options);return mergedOptions.buttons={yes:Lobibox.base.OPTIONS.buttons.yes,no:Lobibox.base.OPTIONS.buttons.no},options=$.extend({},mergedOptions,Lobibox.confirm.DEFAULTS,options)},_init:function(){var me=this;LobiboxBase._init.call(me),me.show()},_afterShow:function(){var me=this,d=$("
");me.$options.iconClass&&d.append($('
').append('')),d.append('
'+me.$options.msg+"
"),me._setContent(d.html()),me._position(),LobiboxBase._afterShow.call(me)}}),Lobibox.confirm.DEFAULTS={title:"Question",width:500},LobiboxAlert.prototype=$.extend({},LobiboxBase,{constructor:LobiboxAlert,_processInput:function(options){var me=this,mergedOptions=LobiboxBase._processInput.call(me,options);return mergedOptions.buttons={ok:Lobibox.base.OPTIONS.buttons.ok},options=$.extend({},mergedOptions,Lobibox.alert.OPTIONS[me.$type],Lobibox.alert.DEFAULTS,options)},_init:function(){var me=this;LobiboxBase._init.call(me),me.show()},_afterShow:function(){var me=this,d=$("
");me.$options.iconClass&&d.append($('
').append('')),d.append('
'+me.$options.msg+"
"),me._setContent(d.html()),me._position(),LobiboxBase._afterShow.call(me)}}),Lobibox.alert.OPTIONS={warning:{title:"Warning"},info:{title:"Information"},success:{title:"Success"},error:{title:"Error"}},Lobibox.alert.DEFAULTS={},LobiboxProgress.prototype=$.extend({},LobiboxBase,{constructor:LobiboxProgress,_processInput:function(options){var me=this,mergedOptions=LobiboxBase._processInput.call(me,options);return options=$.extend({},mergedOptions,Lobibox.progress.DEFAULTS,options)},_init:function(){var me=this;LobiboxBase._init.call(me),me.show()},_afterShow:function(){var me=this;me.$progressBarElement=me.$options.progressTpl?$(me.$options.progressTpl):me._createProgressbar();var label;me.$options.label&&(label=$(""));var innerHTML=$("
").append(label,me.$progressBarElement);me._setContent(innerHTML),me._position(),LobiboxBase._afterShow.call(me)},_createProgressbar:function(){var me=this,outer=$('
').append('
');return me.$options.showProgressLabel&&outer.append(''),outer},setProgress:function(progress){var me=this;if(100!==me.$progress)return progress=Math.min(100,Math.max(0,progress)),me.$progress=progress,me._triggerEvent("progressUpdated"),100===me.$progress&&me._triggerEvent("progressCompleted"),me.$el.find(".lobibox-progress-element").css("width",progress.toFixed(1)+"%"),me.$el.find('[data-role="progress-text"]').html(progress.toFixed(1)+"%"),me},getProgress:function(){return this.$progress}}),Lobibox.progress.DEFAULTS={width:500,showProgressLabel:!0,label:"",progressTpl:!1,progressUpdated:null,progressCompleted:null},LobiboxWindow.prototype=$.extend({},LobiboxBase,{constructor:LobiboxWindow,_processInput:function(options){var me=this,mergedOptions=LobiboxBase._processInput.call(me,options);return options.content&&"function"==typeof options.content&&(options.content=options.content()),options.content instanceof jQuery&&(options.content=options.content.clone()),options=$.extend({},mergedOptions,Lobibox.window.DEFAULTS,options)},_init:function(){var me=this;LobiboxBase._init.call(me),me.setContent(me.$options.content),me.$options.url&&me.$options.autoload?(me.$options.showAfterLoad||me.show(),me.load(function(){me.$options.showAfterLoad&&me.show()})):me.show()},_afterShow:function(){var me=this;me._position(),LobiboxBase._afterShow.call(me)},setParams:function(params){var me=this;return me.$options.params=params,me},getParams:function(){var me=this;return me.$options.params},setLoadMethod:function(method){var me=this;return me.$options.loadMethod=method,me},getLoadMethod:function(){var me=this;return me.$options.loadMethod},setContent:function(content){var me=this;return me.$options.content=content,me.$el.find(".lobibox-body").html("").append(content),me},getContent:function(){var me=this;return me.$options.content},setUrl:function(url){return this.$options.url=url,this},getUrl:function(){return this.$options.url},load:function(callback){var me=this;return me.$options.url?($.ajax(me.$options.url,{method:me.$options.loadMethod,data:me.$options.params}).done(function(res){me.setContent(res),callback&&"function"==typeof callback&&callback(res)}),me):me}}),Lobibox.window.DEFAULTS={width:480,height:600,content:"",url:"",draggable:!0,autoload:!0,loadMethod:"GET",showAfterLoad:!0,params:{}}}(),Math.randomString=function(n){for(var text="",possible="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",i=0;n>i;i++)text+=possible.charAt(Math.floor(Math.random()*possible.length));return text};var Lobibox=Lobibox||{};!function(){var LobiboxNotify=function(type,options){this.$type=null,this.$options=null,this.$el=null;var me=this,_processInput=function(options){return("mini"===options.size||"large"===options.size)&&(options=$.extend({},Lobibox.notify.OPTIONS[options.size],options)),options=$.extend({},Lobibox.notify.OPTIONS[me.$type],Lobibox.notify.DEFAULTS,options),"mini"!==options.size&&options.title===!0?options.title=Lobibox.notify.OPTIONS[me.$type].title:"mini"===options.size&&options.title===!0&&(options.title=!1),options.icon===!0&&(options.icon=Lobibox.notify.OPTIONS.icons[options.iconSource][me.$type]),options.sound===!0&&(options.sound=Lobibox.notify.OPTIONS[me.$type].sound),options.sound&&(options.sound=options.soundPath+options.sound+options.soundExt),options},_init=function(){var $notify=_createNotify();if("mini"===me.$options.size&&$notify.addClass("notify-mini"),"string"==typeof me.$options.position){var $wrapper=_createNotifyWrapper();_appendInWrapper($notify,$wrapper),$wrapper.hasClass("center")&&$wrapper.css("margin-left","-"+$wrapper.width()/2+"px")}else $("body").append($notify),$notify.css({position:"fixed",left:me.$options.position.left,top:me.$options.position.top});if(me.$el=$notify,me.$options.sound){var snd=new Audio(me.$options.sound);snd.play()}me.$options.rounded&&me.$el.addClass("rounded")},_appendInWrapper=function($el,$wrapper){if("normal"===me.$options.size)$wrapper.hasClass("bottom")?$wrapper.prepend($el):$wrapper.append($el);else if("mini"===me.$options.size)$wrapper.hasClass("bottom")?$wrapper.prepend($el):$wrapper.append($el);else if("large"===me.$options.size){var tabPane=_createTabPane().append($el),$li=_createTabControl(tabPane.attr("id"));$wrapper.find(".lb-notify-wrapper").append(tabPane),$wrapper.find(".lb-notify-tabs").append($li),_activateTab($li),$li.find(">a").click(function(){_activateTab($li)})}},_activateTab=function($li){$li.closest(".lb-notify-tabs").find(">li").removeClass("active"),$li.addClass("active");var $current=$($li.find(">a").attr("href"));$current.closest(".lb-notify-wrapper").find(">.lb-tab-pane").removeClass("active"),$current.addClass("active")},_createTabControl=function(tabPaneId){var $li=$("
  • ",{"class":Lobibox.notify.OPTIONS[me.$type]["class"]});return $("
    ",{href:"#"+tabPaneId}).append('').appendTo($li),$li},_createTabPane=function(){return $("
    ",{"class":"lb-tab-pane",id:Math.randomString(10)})},_createNotifyWrapper=function(){var $wrapper,selector=("large"===me.$options.size?".lobibox-notify-wrapper-large":".lobibox-notify-wrapper")+"."+me.$options.position.replace(/\s/gi,".");return $wrapper=$(selector),0===$wrapper.length&&($wrapper=$("
    ").addClass(selector.replace(/\./g," ").trim()).appendTo($("body")),"large"===me.$options.size&&$wrapper.append($('
      ')).append($('
      '))),$wrapper},_createNotify=function(){var $iconEl,$innerIconEl,$iconWrapper,$body,$msg,OPTS=Lobibox.notify.OPTIONS,$notify=$("
      ",{"class":"lobibox-notify "+OPTS[me.$type]["class"]+" "+OPTS["class"]+" "+me.$options.showClass});return $iconWrapper=$('
      ').appendTo($notify),$iconEl=$('
      ').appendTo($iconWrapper),$innerIconEl=$("
      ").appendTo($iconEl),me.$options.img?$innerIconEl.append(''):me.$options.icon?$innerIconEl.append('
      '):$notify.addClass("without-icon"),$msg=$('
      '+me.$options.msg+"
      "),me.$options.messageHeight!==!1&&$msg.css("max-height",me.$options.messageHeight),$body=$("
      ",{"class":"lobibox-notify-body"}).append($msg).appendTo($notify),me.$options.title&&$body.prepend('
      '+me.$options.title+"
      "),_addCloseButton($notify),("normal"===me.$options.size||"mini"===me.$options.size)&&(_addCloseOnClick($notify),_addDelay($notify)),me.$options.width&&$notify.css("width",_calculateWidth(me.$options.width)),$notify},_addCloseButton=function($el){me.$options.closable&&$('×').click(function(){me.remove()}).appendTo($el)},_addCloseOnClick=function($el){me.$options.closeOnClick&&$el.click(function(){me.remove()})},_addDelay=function($el){if(me.$options.delay){if(me.$options.delayIndicator){var delay=$('
      ');$el.append(delay)}var time=0,interval=1e3/30,timer=setInterval(function(){time+=interval;var width=100*time/me.$options.delay;width>=100&&(width=100,me.remove(),timer=clearInterval(timer)),me.$options.delayIndicator&&delay.find("div").css("width",width+"%")},interval)}},_findTabToActivate=function($li){var $itemToActivate=$li.prev();return 0===$itemToActivate.length&&($itemToActivate=$li.next()),0===$itemToActivate.length?null:$itemToActivate},_calculateWidth=function(width){return width=Math.min($(window).outerWidth(),width)};this.remove=function(){me.$el.removeClass(me.$options.showClass).addClass(me.$options.hideClass);var parent=me.$el.parent(),wrapper=parent.closest(".lobibox-notify-wrapper-large"),href="#"+parent.attr("id"),$li=wrapper.find('>.lb-notify-tabs>li:has(a[href="'+href+'"])');return $li.addClass(Lobibox.notify.OPTIONS["class"]).addClass(me.$options.hideClass),setTimeout(function(){if("normal"===me.$options.size||"mini"===me.$options.size)me.$el.remove();else if("large"===me.$options.size){var $newLi=_findTabToActivate($li);$newLi&&_activateTab($newLi),$li.remove(),parent.remove()}},500),me},this.$type=type,this.$options=_processInput(options),_init()};Lobibox.notify=function(type,options){if(["default","info","warning","error","success"].indexOf(type)>-1){var lobibox=new LobiboxNotify(type,options);return lobibox.$el.data("lobibox",lobibox),lobibox}},Lobibox.notify.closeAll=function(){var ll=$(".lobibox-notify");ll.each(function(ind,el){$(el).data("lobibox").remove()})},Lobibox.notify.DEFAULTS={title:!0,size:"normal",soundPath:"sounds/",soundExt:".ogg",showClass:"fadeInDown",hideClass:"zoomOut",icon:!0,msg:"",img:null,closable:!0,hideCloseButton:!1,delay:5e3,delayIndicator:!0,closeOnClick:!0,width:400,sound:!0,position:"bottom right",iconSource:"bootstrap",rounded:!1,messageHeight:60},Lobibox.notify.OPTIONS={"class":"animated-fast",large:{width:500,messageHeight:96},mini:{"class":"notify-mini",messageHeight:32},"default":{"class":"lobibox-notify-default",title:"Default",sound:!1},success:{"class":"lobibox-notify-success",title:"Success",sound:"sound2"},error:{"class":"lobibox-notify-error",title:"Error",sound:"sound4"},warning:{"class":"lobibox-notify-warning",title:"Warning",sound:"sound5"},info:{"class":"lobibox-notify-info",title:"Information",sound:"sound6"},icons:{bootstrap:{success:"glyphicon glyphicon-ok-sign",error:"glyphicon glyphicon-remove-sign",warning:"glyphicon glyphicon-exclamation-sign",info:"glyphicon glyphicon-info-sign"},fontAwesome:{success:"fa fa-check-circle",error:"fa fa-times-circle",warning:"fa fa-exclamation-circle",info:"fa fa-info-circle"}}}}(); \ No newline at end of file diff --git a/public/plugins/lobibox/js/notifications.js b/public/plugins/lobibox/js/notifications.js new file mode 100755 index 0000000..aa4ee7c --- /dev/null +++ b/public/plugins/lobibox/js/notifications.js @@ -0,0 +1,393 @@ +//Author : @arboshiki +/** + * Generates random string of n length. + * String contains only letters and numbers + * + * @param {int} n + * @returns {String} + */ +Math.randomString = function (n) { + var text = ""; + var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + + for (var i = 0; i < n; i++) + text += possible.charAt(Math.floor(Math.random() * possible.length)); + + return text; +}; +var Lobibox = Lobibox || {}; +(function () { + + var LobiboxNotify = function (type, options) { +//------------------------------------------------------------------------------ +//----------------PROTOTYPE VARIABLES------------------------------------------- +//------------------------------------------------------------------------------ + this.$type = null; + this.$options = null; + this.$el = null; +//------------------------------------------------------------------------------ +//-----------------PRIVATE VARIABLES-------------------------------------------- +//------------------------------------------------------------------------------ + var me = this; +//------------------------------------------------------------------------------ +//-----------------PRIVATE FUNCTIONS-------------------------------------------- +//------------------------------------------------------------------------------ + var _processInput = function (options) { + + if (options.size === 'mini' || options.size === 'large') { + options = $.extend({}, Lobibox.notify.OPTIONS[options.size], options); + } + options = $.extend({}, Lobibox.notify.OPTIONS[me.$type], Lobibox.notify.DEFAULTS, options); + + if (options.size !== 'mini' && options.title === true) { + options.title = Lobibox.notify.OPTIONS[me.$type].title; + } else if (options.size === 'mini' && options.title === true) { + options.title = false; + } + if (options.icon === true) { + options.icon = Lobibox.notify.OPTIONS.icons[options.iconSource][me.$type]; + } + if (options.sound === true) { + options.sound = Lobibox.notify.OPTIONS[me.$type].sound; + } + if (options.sound) { + options.sound = options.soundPath + options.sound + options.soundExt; + } + return options; + }; + var _init = function () { + // Create notification + var $notify = _createNotify(); + if (me.$options.size === 'mini'){ + $notify.addClass('notify-mini'); + } + + if (typeof me.$options.position === 'string'){ + var $wrapper = _createNotifyWrapper(); + _appendInWrapper($notify, $wrapper); + if ($wrapper.hasClass('center')){ + $wrapper.css('margin-left', '-'+($wrapper.width()/2)+"px"); + } + } else { + $('body').append($notify); + $notify.css({ + 'position': 'fixed', + left: me.$options.position.left, + top: me.$options.position.top, + }) + } + + me.$el = $notify; + if (me.$options.sound) { + var snd = new Audio(me.$options.sound); // buffers automatically when created + snd.play(); + } + if (me.$options.rounded){ + me.$el.addClass('rounded'); + } + }; + var _appendInWrapper = function ($el, $wrapper) { + if (me.$options.size === 'normal') { + if ($wrapper.hasClass('bottom')){ + $wrapper.prepend($el); + } else { + $wrapper.append($el); + } + + } else if (me.$options.size === 'mini') { + if ($wrapper.hasClass('bottom')){ + $wrapper.prepend($el); + } else { + $wrapper.append($el); + } + } else if (me.$options.size === 'large') { + var tabPane = _createTabPane().append($el); + var $li = _createTabControl(tabPane.attr('id')); + $wrapper.find('.lb-notify-wrapper').append(tabPane); + $wrapper.find('.lb-notify-tabs').append($li); + _activateTab($li); + $li.find('>a').click(function () { + _activateTab($li); + }); + } + }; + var _activateTab = function ($li) { + $li.closest('.lb-notify-tabs').find('>li').removeClass('active'); + $li.addClass('active'); + var $current = $($li.find('>a').attr('href')); + $current.closest('.lb-notify-wrapper').find('>.lb-tab-pane').removeClass('active'); + $current.addClass('active') + }; + var _createTabControl = function (tabPaneId) { + var $li = $('
    • ', { + 'class': Lobibox.notify.OPTIONS[me.$type]['class'] + }); + $('', { + 'href': '#' + tabPaneId + }).append('') + .appendTo($li); + return $li; + }; + var _createTabPane = function () { + return $('
      ', { + 'class': 'lb-tab-pane', + 'id': Math.randomString(10) + }) + }; + var _createNotifyWrapper = function () { + var selector = (me.$options.size === 'large' ? '.lobibox-notify-wrapper-large' : '.lobibox-notify-wrapper') + + "." + me.$options.position.replace(/\s/gi, '.'), + $wrapper; + + //var classes = me.$options.position.split(" "); + $wrapper = $(selector); + if ($wrapper.length === 0) { + $wrapper = $('
      ') + .addClass(selector.replace(/\./g, ' ').trim()) + .appendTo($('body')); + if (me.$options.size === 'large') { + $wrapper.append($('
        ')) + .append($('
        ')); + } + } + return $wrapper; + }; + var _createNotify = function () { + var OPTS = Lobibox.notify.OPTIONS, + $iconEl, + $innerIconEl, + $iconWrapper, + $body, + $msg, + $notify = $('
        ', { + 'class': 'lobibox-notify ' + OPTS[me.$type]['class'] + ' ' + OPTS['class'] + ' ' + me.$options.showClass + }); + + $iconWrapper = $('
        ').appendTo($notify); + $iconEl = $('
        ').appendTo($iconWrapper); + $innerIconEl = $('
        ').appendTo($iconEl); + + // Add image or icon depending on given parameters + if (me.$options.img) { + $innerIconEl.append(''); + } else if (me.$options.icon) { + $innerIconEl.append('
        '); + } else { + $notify.addClass('without-icon'); + } + // Create body, append title and message in body and append body in notification + $msg = $('
        ' + me.$options.msg + '
        '); + + if (me.$options.messageHeight !== false){ + $msg.css('max-height', me.$options.messageHeight); + } + + $body = $('
        ', { + 'class': 'lobibox-notify-body' + }).append($msg).appendTo($notify); + + if (me.$options.title) { + $body.prepend('
        ' + me.$options.title + '
        '); + } + _addCloseButton($notify); + if (me.$options.size === 'normal' || me.$options.size === 'mini') { + _addCloseOnClick($notify); + _addDelay($notify); + } + + // Give width to notification + if (me.$options.width) { + $notify.css('width', _calculateWidth(me.$options.width)); + } + + return $notify; + }; + var _addCloseButton = function ($el) { + if (!me.$options.closable) { + return; + } + $('×').click(function () { + me.remove(); + }).appendTo($el); + }; + var _addCloseOnClick = function ($el) { + if (!me.$options.closeOnClick) { + return; + } + $el.click(function () { + me.remove(); + }); + }; + var _addDelay = function ($el) { + if (!me.$options.delay) { + return; + } + if (me.$options.delayIndicator) { + var delay = $('
        '); + $el.append(delay); + } + var time = 0; + var interval = 1000 / 30; + var timer = setInterval(function () { + time += interval; + var width = 100 * time / me.$options.delay; + if (width >= 100) { + width = 100; + me.remove(); + timer = clearInterval(timer); + } + if (me.$options.delayIndicator) { + delay.find('div').css('width', width + "%"); + } + + }, interval); + }; + var _findTabToActivate = function ($li) { + var $itemToActivate = $li.prev(); + if ($itemToActivate.length === 0) { + $itemToActivate = $li.next(); + } + if ($itemToActivate.length === 0) { + return null; + } + return $itemToActivate; + }; + var _calculateWidth = function (width) { + width = Math.min($(window).outerWidth(), width); + return width; + }; +//------------------------------------------------------------------------------ +//----------------PROTOTYPE FUNCTIONS------------------------------------------- +//------------------------------------------------------------------------------ + /** + * Delete the notification + * + * @returns {LobiboxNotify} + */ + this.remove = function () { + me.$el.removeClass(me.$options.showClass) + .addClass(me.$options.hideClass); + var parent = me.$el.parent(); + var wrapper = parent.closest('.lobibox-notify-wrapper-large'); + + var href = '#' + parent.attr('id'); + + var $li = wrapper.find('>.lb-notify-tabs>li:has(a[href="' + href + '"])'); + $li.addClass(Lobibox.notify.OPTIONS['class']) + .addClass(me.$options.hideClass); + setTimeout(function () { + if (me.$options.size === 'normal' || me.$options.size === 'mini') { + me.$el.remove(); + } else if (me.$options.size === 'large') { + + var $newLi = _findTabToActivate($li); + if ($newLi) { + _activateTab($newLi); + } + $li.remove(); + parent.remove(); + } + }, 500); + return me; + }; +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + this.$type = type; + this.$options = _processInput(options); + _init(); + }; + + Lobibox.notify = function (type, options) { + if (["default", "info", "warning", "error", "success"].indexOf(type) > -1) { + var lobibox = new LobiboxNotify(type, options); + lobibox.$el.data('lobibox', lobibox); + return lobibox; + } + }; + Lobibox.notify.closeAll = function(){ + var ll = $('.lobibox-notify'); + ll.each(function(ind, el){ + var notify =$(el).data('lobibox') .remove(); + }); + }; + //User can set default options to this variable + Lobibox.notify.DEFAULTS = { + title: true, // Title of notification. If you do not include the title in options it will automatically takes its value + //from Lobibox.notify.OPTIONS object depending of the type of the notifications or set custom string. Set this false to disable title + size: 'normal', // normal, mini, large + soundPath: 'plugins/lobibox/sounds/', // The folder path where sounds are located + soundExt: '.ogg', // Default extension for all sounds + showClass: 'fadeInDown', // Show animation class. + hideClass: 'zoomOut', // Hide animation class. + icon: true, // Icon of notification. Leave as is for default icon or set custom string + msg: '', // Message of notification + img: null, // Image source string + closable: true, // Make notifications closable + hideCloseButton: false, // Notification may be closable but you can hide close button and it will be closed by clicking on notification itsef + delay: 5000, // Hide notification after this time (in miliseconds) + delayIndicator: true, // Show timer indicator + closeOnClick: true, // Close notifications by clicking on them + width: 400, // Width of notification box + sound: true, // Sound of notification. Set this false to disable sound. Leave as is for default sound or set custom soud path + // Place to show notification. Available options: "top left", "top right", "bottom left", "bottom right", "center top", "center bottom" + // It can also be object {left: number, top: number} to position notification at any place + position: "bottom right", + iconSource: 'bootstrap', // "bootstrap" or "fontAwesome" the library which will be used for icons + rounded: false, // Whether to make notification corners rounded + messageHeight: 60 // Notification message maximum height + }; + //This variable is necessary. + Lobibox.notify.OPTIONS = { + 'class': 'animated-fast', + large: { + width: 500, + messageHeight: 96 + }, + mini: { + 'class': 'notify-mini', + messageHeight: 32 + }, + default: { + 'class': 'lobibox-notify-default', + 'title': 'Default', + sound: false + }, + success: { + 'class': 'lobibox-notify-success', + 'title': 'Success', + sound: 'sound2' + }, + error: { + 'class': 'lobibox-notify-error', + 'title': 'Error', + sound: 'sound4' + }, + warning: { + 'class': 'lobibox-notify-warning', + 'title': 'Warning', + sound: 'sound5' + }, + info: { + 'class': 'lobibox-notify-info', + 'title': 'Information', + sound: 'sound6' + }, + icons: { + bootstrap: { + success: 'checkmark icon', + error: 'remove circle icon', + warning: 'warning sign icon', + info: 'info circle icon' + }, + fontAwesome: { + success: 'fa fa-check-circle', + error: 'fa fa-times-circle', + warning: 'fa fa-exclamation-circle', + info: 'fa fa-info-circle' + } + } + }; +})(); + + diff --git a/public/plugins/nicescrool/jquery.nicescroll.min.js b/public/plugins/nicescrool/jquery.nicescroll.min.js new file mode 100755 index 0000000..33f1a31 --- /dev/null +++ b/public/plugins/nicescrool/jquery.nicescroll.min.js @@ -0,0 +1,2 @@ +!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){"use strict";function h(){var a=document.getElementsByTagName("script"),b=a.length?a[a.length-1].src.split("?")[0]:"";return b.split("/").length>0?b.split("/").slice(0,-1).join("/")+"/":""}function w(a,b,c){for(var d=0;d=11,e.isieedge12=navigator.userAgent.match(/Edge\/12\./),e.isieedge="msOverflowStyle"in a,e.ismodernie=e.isie11||e.isieedge,e.isie9mobile=/iemobile.9/i.test(c),e.isie9mobile&&(e.isie9=!1),e.isie7mobile=!e.isie9mobile&&e.isie7&&/iemobile/i.test(c),e.ismozilla="MozAppearance"in b,e.iswebkit="WebkitAppearance"in b,e.ischrome="chrome"in window,e.ischrome38=e.ischrome&&"touchAction"in b,e.ischrome22=!e.ischrome38&&e.ischrome&&e.haspointerlock,e.ischrome26=!e.ischrome38&&e.ischrome&&"transition"in b,e.cantouch="ontouchstart"in document.documentElement||"ontouchstart"in window,e.hasw3ctouch=(window.PointerEvent||!1)&&(navigator.MaxTouchPoints>0||navigator.msMaxTouchPoints>0),e.hasmstouch=!e.hasw3ctouch&&(window.MSPointerEvent||!1),e.ismac=/^mac$/i.test(d),e.isios=e.cantouch&&/iphone|ipad|ipod/i.test(d),e.isios4=e.isios&&!("seal"in Object),e.isios7=e.isios&&"webkitHidden"in document,e.isios8=e.isios&&"hidden"in document,e.isandroid=/android/i.test(c),e.haseventlistener="addEventListener"in a,e.trstyle=!1,e.hastransform=!1,e.hastranslate3d=!1,e.transitionstyle=!1,e.hastransition=!1,e.transitionend=!1;var f,g=["transform","msTransform","webkitTransform","MozTransform","OTransform"];for(f=0;f0;){if(9==a[0].nodeType)return!1;var b=a.css("zIndex");if(!isNaN(b)&&0!=b)return parseInt(b);a=a.parent()}return!1}function z(a,b,c){var d=a.css(b),e=parseFloat(d);if(isNaN(e)){e=y[d]||0;var f=3==e?c?i.win.outerHeight()-i.win.innerHeight():i.win.outerWidth()-i.win.innerWidth():1;return i.isie8&&e&&(e+=1),f?e:0}return e}function A(a,b,c,d){i._bind(a,b,function(d){var d=d?d:window.event,e={original:d,target:d.target||d.srcElement,type:"wheel",deltaMode:"MozMousePixelScroll"==d.type?0:1,deltaX:0,deltaZ:0,preventDefault:function(){return d.preventDefault?d.preventDefault():d.returnValue=!1,!1},stopImmediatePropagation:function(){d.stopImmediatePropagation?d.stopImmediatePropagation():d.cancelBubble=!0}};return"mousewheel"==b?(d.wheelDeltaX&&(e.deltaX=-1/40*d.wheelDeltaX),d.wheelDeltaY&&(e.deltaY=-1/40*d.wheelDeltaY),!e.deltaY&&!e.deltaX&&(e.deltaY=-1/40*d.wheelDelta)):e.deltaY=d.detail,c.call(a,e)},d)}function B(a,b,c){var d,e;if(0==a.deltaMode?(d=-Math.floor(a.deltaX*(i.opt.mousescrollstep/54)),e=-Math.floor(a.deltaY*(i.opt.mousescrollstep/54))):1==a.deltaMode&&(d=-Math.floor(a.deltaX*i.opt.mousescrollstep),e=-Math.floor(a.deltaY*i.opt.mousescrollstep)),b&&i.opt.oneaxismousemode&&0==d&&e&&(d=e,e=0,c)){var f=0>d?i.getScrollLeft()>=i.page.maxw:i.getScrollLeft()<=0;f&&(e=d,d=0)}if(i.isrtlmode&&(d=-d),d&&(i.scrollmom&&i.scrollmom.stop(),i.lastdeltax+=d,i.debounced("mousewheelx",function(){var a=i.lastdeltax;i.lastdeltax=0,i.rail.drag||i.doScrollLeftBy(a)},15)),e){if(i.opt.nativeparentscrolling&&c&&!i.ispage&&!i.zoomactive)if(0>e){if(i.getScrollTop()>=i.page.maxh)return!0}else if(i.getScrollTop()<=0)return!0;i.scrollmom&&i.scrollmom.stop(),i.lastdeltay+=e,i.synched("mousewheely",function(){var a=i.lastdeltay;i.lastdeltay=0,i.rail.drag||i.doScrollBy(a)},15)}return a.stopImmediatePropagation(),a.preventDefault()}var i=this;if(this.version="3.6.8",this.name="nicescroll",this.me=h,this.opt={doc:g("body"),win:!1},g.extend(this.opt,o),this.opt.snapbackspeed=80,a)for(var l in i.opt)void 0!==a[l]&&(i.opt[l]=a[l]);if(i.opt.disablemutationobserver&&(n=!1),this.doc=i.opt.doc,this.iddoc=this.doc&&this.doc[0]?this.doc[0].id||"":"",this.ispage=/^BODY|HTML/.test(i.opt.win?i.opt.win[0].nodeName:this.doc[0].nodeName),this.haswrapper=i.opt.win!==!1,this.win=i.opt.win||(this.ispage?g(window):this.doc),this.docscroll=this.ispage&&!this.haswrapper?g(window):this.win,this.body=g("body"),this.viewport=!1,this.isfixed=!1,this.iframe=!1,this.isiframe="IFRAME"==this.doc[0].nodeName&&"IFRAME"==this.win[0].nodeName,this.istextarea="TEXTAREA"==this.win[0].nodeName,this.forcescreen=!1,this.canshowonmouseevent="scroll"!=i.opt.autohidemode,this.onmousedown=!1,this.onmouseup=!1,this.onmousemove=!1,this.onmousewheel=!1,this.onkeypress=!1,this.ongesturezoom=!1,this.onclick=!1,this.onscrollstart=!1,this.onscrollend=!1,this.onscrollcancel=!1,this.onzoomin=!1,this.onzoomout=!1,this.view=!1,this.page=!1,this.scroll={x:0,y:0},this.scrollratio={x:0,y:0},this.cursorheight=20,this.scrollvaluemax=0,"auto"==this.opt.rtlmode){var m=this.win[0]==window?this.body:this.win,p=m.css("writing-mode")||m.css("-webkit-writing-mode")||m.css("-ms-writing-mode")||m.css("-moz-writing-mode");"horizontal-tb"==p||"lr-tb"==p||""==p?(this.isrtlmode="rtl"==m.css("direction"),this.isvertical=!1):(this.isrtlmode="vertical-rl"==p||"tb"==p||"tb-rl"==p||"rl-tb"==p,this.isvertical="vertical-rl"==p||"tb"==p||"tb-rl"==p)}else this.isrtlmode=this.opt.rtlmode===!0,this.isvertical=!1;this.scrollrunning=!1,this.scrollmom=!1,this.observer=!1,this.observerremover=!1,this.observerbody=!1;do this.id="ascrail"+e++;while(document.getElementById(this.id));this.rail=!1,this.cursor=!1,this.cursorfreezed=!1,this.selectiondrag=!1,this.zoom=!1,this.zoomactive=!1,this.hasfocus=!1,this.hasmousefocus=!1,this.visibility=!0,this.railslocked=!1,this.locked=!1,this.hidden=!1,this.cursoractive=!0,this.wheelprevented=!1,this.overflowx=i.opt.overflowx,this.overflowy=i.opt.overflowy,this.nativescrollingarea=!1,this.checkarea=0,this.events=[],this.saved={},this.delaylist={},this.synclist={},this.lastdeltax=0,this.lastdeltay=0,this.detected=q();var r=g.extend({},this.detected);this.canhwscroll=r.hastransform&&i.opt.hwacceleration,this.ishwscroll=this.canhwscroll&&i.haswrapper,this.isrtlmode?this.isvertical?this.hasreversehr=!(r.iswebkit||r.isie||r.isie11):this.hasreversehr=!(r.iswebkit||r.isie&&!r.isie10&&!r.isie11):this.hasreversehr=!1,this.istouchcapable=!1,r.cantouch||!r.hasw3ctouch&&!r.hasmstouch?!r.cantouch||r.isios||r.isandroid||!r.iswebkit&&!r.ismozilla||(this.istouchcapable=!0):this.istouchcapable=!0,i.opt.enablemouselockapi||(r.hasmousecapture=!1,r.haspointerlock=!1),this.debounced=function(a,b,c){if(i){var d=i.delaylist[a]||!1;d||(b.call(i),i.delaylist[a]={h:j(function(){i.delaylist[a].fn.call(i),i.delaylist[a]=!1},c)}),i.delaylist[a].fn=b}};var t=!1;this.synched=function(a,b){function c(){t||(j(function(){if(i){t=!1;for(var a in i.synclist){var b=i.synclist[a];b&&b.call(i),i.synclist[a]=!1}}}),t=!0)}return i.synclist[a]=b,c(),a},this.unsynched=function(a){i.synclist[a]&&(i.synclist[a]=!1)},this.css=function(a,b){for(var c in b)i.saved.css.push([a,c,a.css(c)]),a.css(c,b[c])},this.scrollTop=function(a){return void 0===a?i.getScrollTop():i.setScrollTop(a)},this.scrollLeft=function(a){return void 0===a?i.getScrollLeft():i.setScrollLeft(a)};var u=function(a,b,c,d,e,f,g){this.st=a,this.ed=b,this.spd=c,this.p1=d||0,this.p2=e||1,this.p3=f||0,this.p4=g||1,this.ts=(new Date).getTime(),this.df=this.ed-this.st};if(u.prototype={B2:function(a){return 3*a*a*(1-a)},B3:function(a){return 3*a*(1-a)*(1-a)},B4:function(a){return(1-a)*(1-a)*(1-a)},getNow:function(){var a=(new Date).getTime(),b=1-(a-this.ts)/this.spd,c=this.B2(b)+this.B3(b)+this.B4(b);return 0>b?this.ed:this.st+Math.round(this.df*c)},update:function(a,b){return this.st=this.getNow(),this.ed=a,this.spd=b,this.ts=(new Date).getTime(),this.df=this.ed-this.st,this}},this.ishwscroll){this.doc.translate={x:0,y:0,tx:"0px",ty:"0px"},r.hastranslate3d&&r.isios&&this.doc.css("-webkit-backface-visibility","hidden"),this.getScrollTop=function(a){if(!a){var b=v();if(b)return 16==b.length?-b[13]:-b[5];if(i.timerscroll&&i.timerscroll.bz)return i.timerscroll.bz.getNow()}return i.doc.translate.y},this.getScrollLeft=function(a){if(!a){var b=v();if(b)return 16==b.length?-b[12]:-b[4];if(i.timerscroll&&i.timerscroll.bh)return i.timerscroll.bh.getNow()}return i.doc.translate.x},this.notifyScrollEvent=function(a){var b=document.createEvent("UIEvents");b.initUIEvent("scroll",!1,!0,window,1),b.niceevent=!0,a.dispatchEvent(b)};var w=this.isrtlmode?1:-1;r.hastranslate3d&&i.opt.enabletranslate3d?(this.setScrollTop=function(a,b){i.doc.translate.y=a,i.doc.translate.ty=-1*a+"px",i.doc.css(r.trstyle,"translate3d("+i.doc.translate.tx+","+i.doc.translate.ty+",0px)"),b||i.notifyScrollEvent(i.win[0])},this.setScrollLeft=function(a,b){i.doc.translate.x=a,i.doc.translate.tx=a*w+"px",i.doc.css(r.trstyle,"translate3d("+i.doc.translate.tx+","+i.doc.translate.ty+",0px)"),b||i.notifyScrollEvent(i.win[0])}):(this.setScrollTop=function(a,b){i.doc.translate.y=a,i.doc.translate.ty=-1*a+"px",i.doc.css(r.trstyle,"translate("+i.doc.translate.tx+","+i.doc.translate.ty+")"),b||i.notifyScrollEvent(i.win[0])},this.setScrollLeft=function(a,b){i.doc.translate.x=a,i.doc.translate.tx=a*w+"px",i.doc.css(r.trstyle,"translate("+i.doc.translate.tx+","+i.doc.translate.ty+")"),b||i.notifyScrollEvent(i.win[0])})}else this.getScrollTop=function(){return i.docscroll.scrollTop()},this.setScrollTop=function(a){return setTimeout(function(){i&&i.docscroll.scrollTop(a)},1)},this.getScrollLeft=function(){var a;return a=i.hasreversehr?i.detected.ismozilla?i.page.maxw-Math.abs(i.docscroll.scrollLeft()):i.page.maxw-i.docscroll.scrollLeft():i.docscroll.scrollLeft()},this.setScrollLeft=function(a){return setTimeout(function(){return i?(i.hasreversehr&&(a=i.detected.ismozilla?-(i.page.maxw-a):i.page.maxw-a),i.docscroll.scrollLeft(a)):void 0},1)};this.getTarget=function(a){return a?a.target?a.target:a.srcElement?a.srcElement:!1:!1},this.hasParent=function(a,b){if(!a)return!1;for(var c=a.target||a.srcElement||a||!1;c&&c.id!=b;)c=c.parentNode||!1;return c!==!1};var y={thin:1,medium:3,thick:5};this.getDocumentScrollOffset=function(){return{top:window.pageYOffset||document.documentElement.scrollTop,left:window.pageXOffset||document.documentElement.scrollLeft}},this.getOffset=function(){if(i.isfixed){var a=i.win.offset(),b=i.getDocumentScrollOffset();return a.top-=b.top,a.left-=b.left,a}var c=i.win.offset();if(!i.viewport)return c;var d=i.viewport.offset();return{top:c.top-d.top,left:c.left-d.left}},this.updateScrollBar=function(a){var b,c;if(i.ishwscroll)i.rail.css({height:i.win.innerHeight()-(i.opt.railpadding.top+i.opt.railpadding.bottom)}),i.railh&&i.railh.css({width:i.win.innerWidth()-(i.opt.railpadding.left+i.opt.railpadding.right)});else{var d=i.getOffset();if(b={top:d.top,left:d.left-(i.opt.railpadding.left+i.opt.railpadding.right)},b.top+=z(i.win,"border-top-width",!0),b.left+=i.rail.align?i.win.outerWidth()-z(i.win,"border-right-width")-i.rail.width:z(i.win,"border-left-width"),c=i.opt.railoffset,c&&(c.top&&(b.top+=c.top),c.left&&(b.left+=c.left)),i.railslocked||i.rail.css({top:b.top,left:b.left,height:(a?a.h:i.win.innerHeight())-(i.opt.railpadding.top+i.opt.railpadding.bottom)}),i.zoom&&i.zoom.css({top:b.top+1,left:1==i.rail.align?b.left-20:b.left+i.rail.width+4}),i.railh&&!i.railslocked){b={top:d.top,left:d.left},c=i.opt.railhoffset,c&&(c.top&&(b.top+=c.top),c.left&&(b.left+=c.left));var e=i.railh.align?b.top+z(i.win,"border-top-width",!0)+i.win.innerHeight()-i.railh.height:b.top+z(i.win,"border-top-width",!0),f=b.left+z(i.win,"border-left-width");i.railh.css({top:e-(i.opt.railpadding.top+i.opt.railpadding.bottom),left:f,width:i.railh.width})}}},this.doRailClick=function(a,b,c){var d,e,f,g;i.railslocked||(i.cancelEvent(a),b?(d=c?i.doScrollLeft:i.doScrollTop,f=c?(a.pageX-i.railh.offset().left-i.cursorwidth/2)*i.scrollratio.x:(a.pageY-i.rail.offset().top-i.cursorheight/2)*i.scrollratio.y,d(f)):(d=c?i.doScrollLeftBy:i.doScrollBy,f=c?i.scroll.x:i.scroll.y,g=c?a.pageX-i.railh.offset().left:a.pageY-i.rail.offset().top,e=c?i.view.w:i.view.h,d(f>=g?e:-e)))},i.hasanimationframe=j,i.hascancelanimationframe=k,i.hasanimationframe?i.hascancelanimationframe||(k=function(){i.cancelAnimationFrame=!0}):(j=function(a){return setTimeout(a,15-Math.floor(+new Date/1e3)%16)},k=clearTimeout),this.init=function(){if(i.saved.css=[],r.isie7mobile)return!0;if(r.isoperamini)return!0;r.isie10?"-ms-touch-action":"touch-action";r.hasmstouch&&i.css(i.ispage?g("html"):i.win,{_touchaction:"none"});var e=r.ismodernie||r.isie10?{"-ms-overflow-style":"none"}:{"overflow-y":"hidden"};if(i.zindex="auto",i.ispage||"auto"!=i.opt.zindex?i.zindex=i.opt.zindex:i.zindex=x()||"auto",!i.ispage&&"auto"!=i.zindex&&i.zindex>f&&(f=i.zindex),i.isie&&0==i.zindex&&"auto"==i.opt.zindex&&(i.zindex="auto"),!i.ispage||!r.cantouch&&!r.isieold&&!r.isie9mobile){var h=i.docscroll;i.ispage&&(h=i.haswrapper?i.win:i.doc),r.isie9mobile||i.css(h,e),i.ispage&&r.isie7&&("BODY"==i.doc[0].nodeName?i.css(g("html"),{"overflow-y":"hidden"}):"HTML"==i.doc[0].nodeName&&i.css(g("body"),e)),!r.isios||i.ispage||i.haswrapper||i.css(g("body"),{"-webkit-overflow-scrolling":"touch"});var j=g(document.createElement("div"));j.css({position:"relative",top:0,"float":"right",width:i.opt.cursorwidth,height:0,"background-color":i.opt.cursorcolor,border:i.opt.cursorborder,"background-clip":"padding-box","-webkit-border-radius":i.opt.cursorborderradius,"-moz-border-radius":i.opt.cursorborderradius,"border-radius":i.opt.cursorborderradius}),j.hborder=parseFloat(j.outerHeight()-j.innerHeight()),j.addClass("nicescroll-cursors"),i.cursor=j;var k=g(document.createElement("div"));k.attr("id",i.id),k.addClass("nicescroll-rails nicescroll-rails-vr");var l,m,o=["left","right","top","bottom"];for(var p in o)m=o[p],l=i.opt.railpadding[m],l?k.css("padding-"+m,l+"px"):i.opt.railpadding[m]=0;k.append(j),k.width=Math.max(parseFloat(i.opt.cursorwidth),j.outerWidth()),k.css({width:k.width+"px",zIndex:i.zindex,background:i.opt.background,cursor:"default"}),k.visibility=!0,k.scrollable=!0,k.align="left"==i.opt.railalign?0:1,i.rail=k,i.rail.drag=!1;var q=!1;!i.opt.boxzoom||i.ispage||r.isieold||(q=document.createElement("div"),i.bind(q,"click",i.doZoom),i.bind(q,"mouseenter",function(){i.zoom.css("opacity",i.opt.cursoropacitymax)}),i.bind(q,"mouseleave",function(){i.zoom.css("opacity",i.opt.cursoropacitymin)}),i.zoom=g(q),i.zoom.css({cursor:"pointer",zIndex:i.zindex,backgroundImage:"url("+i.opt.scriptpath+"zoomico.png)",height:18,width:18,backgroundPosition:"0px 0px"}),i.opt.dblclickzoom&&i.bind(i.win,"dblclick",i.doZoom),r.cantouch&&i.opt.gesturezoom&&(i.ongesturezoom=function(a){return a.scale>1.5&&i.doZoomIn(a),a.scale<.8&&i.doZoomOut(a),i.cancelEvent(a)},i.bind(i.win,"gestureend",i.ongesturezoom))),i.railh=!1;var t;if(i.opt.horizrailenabled){i.css(h,{overflowX:"hidden"});var j=g(document.createElement("div"));j.css({position:"absolute",top:0,height:i.opt.cursorwidth,width:0,backgroundColor:i.opt.cursorcolor,border:i.opt.cursorborder,backgroundClip:"padding-box","-webkit-border-radius":i.opt.cursorborderradius,"-moz-border-radius":i.opt.cursorborderradius,"border-radius":i.opt.cursorborderradius}),r.isieold&&j.css("overflow","hidden"),j.wborder=parseFloat(j.outerWidth()-j.innerWidth()),j.addClass("nicescroll-cursors"),i.cursorh=j,t=g(document.createElement("div")),t.attr("id",i.id+"-hr"),t.addClass("nicescroll-rails nicescroll-rails-hr"),t.height=Math.max(parseFloat(i.opt.cursorwidth),j.outerHeight()),t.css({height:t.height+"px",zIndex:i.zindex,background:i.opt.background}),t.append(j),t.visibility=!0,t.scrollable=!0,t.align="top"==i.opt.railvalign?0:1,i.railh=t,i.railh.drag=!1}if(i.ispage)k.css({position:"fixed",top:0,height:"100%"}),k.align?k.css({right:0}):k.css({left:0}),i.body.append(k),i.railh&&(t.css({position:"fixed",left:0,width:"100%"}),t.align?t.css({bottom:0}):t.css({top:0}),i.body.append(t));else{if(i.ishwscroll){"static"==i.win.css("position")&&i.css(i.win,{position:"relative"});var u="HTML"==i.win[0].nodeName?i.body:i.win;g(u).scrollTop(0).scrollLeft(0),i.zoom&&(i.zoom.css({position:"absolute",top:1,right:0,"margin-right":k.width+4}),u.append(i.zoom)),k.css({position:"absolute",top:0}),k.align?k.css({right:0}):k.css({left:0}),u.append(k),t&&(t.css({position:"absolute",left:0,bottom:0}),t.align?t.css({bottom:0}):t.css({top:0}),u.append(t))}else{i.isfixed="fixed"==i.win.css("position");var v=i.isfixed?"fixed":"absolute";i.isfixed||(i.viewport=i.getViewport(i.win[0])),i.viewport&&(i.body=i.viewport,0==/fixed|absolute/.test(i.viewport.css("position"))&&i.css(i.viewport,{position:"relative"})),k.css({position:v}),i.zoom&&i.zoom.css({position:v}),i.updateScrollBar(),i.body.append(k),i.zoom&&i.body.append(i.zoom),i.railh&&(t.css({position:v}),i.body.append(t))}r.isios&&i.css(i.win,{"-webkit-tap-highlight-color":"rgba(0,0,0,0)","-webkit-touch-callout":"none"}),r.isie&&i.opt.disableoutline&&i.win.attr("hideFocus","true"),r.iswebkit&&i.opt.disableoutline&&i.win.css("outline","none")}if(i.opt.autohidemode===!1?(i.autohidedom=!1,i.rail.css({opacity:i.opt.cursoropacitymax}),i.railh&&i.railh.css({opacity:i.opt.cursoropacitymax})):i.opt.autohidemode===!0||"leave"===i.opt.autohidemode?(i.autohidedom=g().add(i.rail),r.isie8&&(i.autohidedom=i.autohidedom.add(i.cursor)),i.railh&&(i.autohidedom=i.autohidedom.add(i.railh)),i.railh&&r.isie8&&(i.autohidedom=i.autohidedom.add(i.cursorh))):"scroll"==i.opt.autohidemode?(i.autohidedom=g().add(i.rail),i.railh&&(i.autohidedom=i.autohidedom.add(i.railh))):"cursor"==i.opt.autohidemode?(i.autohidedom=g().add(i.cursor),i.railh&&(i.autohidedom=i.autohidedom.add(i.cursorh))):"hidden"==i.opt.autohidemode&&(i.autohidedom=!1,i.hide(),i.railslocked=!1),r.isie9mobile){i.scrollmom=new s(i),i.onmangotouch=function(){var a=i.getScrollTop(),b=i.getScrollLeft();if(a==i.scrollmom.lastscrolly&&b==i.scrollmom.lastscrollx)return!0;var c=a-i.mangotouch.sy,d=b-i.mangotouch.sx,e=Math.round(Math.sqrt(Math.pow(d,2)+Math.pow(c,2)));if(0!=e){var f=0>c?-1:1,g=0>d?-1:1,h=+new Date;if(i.mangotouch.lazy&&clearTimeout(i.mangotouch.lazy),h-i.mangotouch.tm>80||i.mangotouch.dry!=f||i.mangotouch.drx!=g)i.scrollmom.stop(),i.scrollmom.reset(b,a),i.mangotouch.sy=a,i.mangotouch.ly=a,i.mangotouch.sx=b,i.mangotouch.lx=b,i.mangotouch.dry=f,i.mangotouch.drx=g,i.mangotouch.tm=h;else{i.scrollmom.stop(),i.scrollmom.update(i.mangotouch.sx-d,i.mangotouch.sy-c),i.mangotouch.tm=h;var j=Math.max(Math.abs(i.mangotouch.ly-a),Math.abs(i.mangotouch.lx-b));i.mangotouch.ly=a,i.mangotouch.lx=b,j>2&&(i.mangotouch.lazy=setTimeout(function(){i.mangotouch.lazy=!1,i.mangotouch.dry=0,i.mangotouch.drx=0,i.mangotouch.tm=0,i.scrollmom.doMomentum(30)},100))}}};var w=i.getScrollTop(),y=i.getScrollLeft();i.mangotouch={sy:w,ly:w,dry:0,sx:y,lx:y,drx:0,lazy:!1,tm:0},i.bind(i.docscroll,"scroll",i.onmangotouch)}else{if(r.cantouch||i.istouchcapable||i.opt.touchbehavior||r.hasmstouch){i.scrollmom=new s(i),i.ontouchstart=function(a){if(a.pointerType&&2!=a.pointerType&&"touch"!=a.pointerType)return!1;if(i.hasmoving=!1,!i.railslocked){var b;if(r.hasmstouch)for(b=a.target?a.target:!1;b;){var c=g(b).getNiceScroll();if(c.length>0&&c[0].me==i.me)break;if(c.length>0)return!1;if("DIV"==b.nodeName&&b.id==i.id)break;b=b.parentNode?b.parentNode:!1}if(i.cancelScroll(),b=i.getTarget(a)){var d=/INPUT/i.test(b.nodeName)&&/range/i.test(b.type);if(d)return i.stopPropagation(a)}if(!("clientX"in a)&&"changedTouches"in a&&(a.clientX=a.changedTouches[0].clientX,a.clientY=a.changedTouches[0].clientY),i.forcescreen){var e=a;a={original:a.original?a.original:a},a.clientX=e.screenX,a.clientY=e.screenY}if(i.rail.drag={x:a.clientX,y:a.clientY,sx:i.scroll.x,sy:i.scroll.y,st:i.getScrollTop(),sl:i.getScrollLeft(),pt:2,dl:!1},i.ispage||!i.opt.directionlockdeadzone)i.rail.drag.dl="f";else{var f={w:g(window).width(),h:g(window).height()},h={w:Math.max(document.body.scrollWidth,document.documentElement.scrollWidth),h:Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},j=Math.max(0,h.h-f.h),k=Math.max(0,h.w-f.w);!i.rail.scrollable&&i.railh.scrollable?i.rail.drag.ck=j>0?"v":!1:i.rail.scrollable&&!i.railh.scrollable?i.rail.drag.ck=k>0?"h":!1:i.rail.drag.ck=!1,i.rail.drag.ck||(i.rail.drag.dl="f")}if(i.opt.touchbehavior&&i.isiframe&&r.isie){var l=i.win.position();i.rail.drag.x+=l.left,i.rail.drag.y+=l.top}if(i.hasmoving=!1,i.lastmouseup=!1,i.scrollmom.reset(a.clientX,a.clientY),!r.cantouch&&!this.istouchcapable&&!a.pointerType){var m=b?/INPUT|SELECT|TEXTAREA/i.test(b.nodeName):!1;if(!m)return!i.ispage&&r.hasmousecapture&&b.setCapture(),i.opt.touchbehavior?(b.onclick&&!b._onclick&&(b._onclick=b.onclick,b.onclick=function(a){return i.hasmoving?!1:void b._onclick.call(this,a)}),i.cancelEvent(a)):i.stopPropagation(a);/SUBMIT|CANCEL|BUTTON/i.test(g(b).attr("type"))&&(pc={tg:b,click:!1},i.preventclick=pc)}}},i.ontouchend=function(a){if(!i.rail.drag)return!0;if(2==i.rail.drag.pt){if(a.pointerType&&2!=a.pointerType&&"touch"!=a.pointerType)return!1;if(i.scrollmom.doMomentum(),i.rail.drag=!1,i.hasmoving&&(i.lastmouseup=!0,i.hideCursor(),r.hasmousecapture&&document.releaseCapture(),!r.cantouch))return i.cancelEvent(a)}else if(1==i.rail.drag.pt)return i.onmouseup(a)};var z=i.opt.touchbehavior&&i.isiframe&&!r.hasmousecapture;i.ontouchmove=function(a,b){if(!i.rail.drag)return!1;if(a.targetTouches&&i.opt.preventmultitouchscrolling&&a.targetTouches.length>1)return!1;if(a.pointerType&&2!=a.pointerType&&"touch"!=a.pointerType)return!1;if(2==i.rail.drag.pt){if(r.cantouch&&r.isios&&void 0===a.original)return!0;i.hasmoving=!0,i.preventclick&&!i.preventclick.click&&(i.preventclick.click=i.preventclick.tg.onclick||!1,i.preventclick.tg.onclick=i.onpreventclick);var c=g.extend({original:a},a);if(a=c,"changedTouches"in a&&(a.clientX=a.changedTouches[0].clientX,a.clientY=a.changedTouches[0].clientY),i.forcescreen){var d=a;a={original:a.original?a.original:a},a.clientX=d.screenX,a.clientY=d.screenY}var e,f;if(f=e=0,z&&!b){var h=i.win.position();f=-h.left,e=-h.top}var j=a.clientY+e,k=j-i.rail.drag.y,l=a.clientX+f,m=l-i.rail.drag.x,n=i.rail.drag.st-k;i.ishwscroll&&i.opt.bouncescroll?0>n?n=Math.round(n/2):n>i.page.maxh&&(n=i.page.maxh+Math.round((n-i.page.maxh)/2)):(0>n&&(n=0,j=0),n>i.page.maxh&&(n=i.page.maxh,j=0));var o;i.railh&&i.railh.scrollable&&(o=i.isrtlmode?m-i.rail.drag.sl:i.rail.drag.sl-m,i.ishwscroll&&i.opt.bouncescroll?0>o?o=Math.round(o/2):o>i.page.maxw&&(o=i.page.maxw+Math.round((o-i.page.maxw)/2)):(0>o&&(o=0,l=0),o>i.page.maxw&&(o=i.page.maxw,l=0)));var p=!1;if(i.rail.drag.dl)p=!0,"v"==i.rail.drag.dl?o=i.rail.drag.sl:"h"==i.rail.drag.dl&&(n=i.rail.drag.st);else{var q=Math.abs(k),s=Math.abs(m),t=i.opt.directionlockdeadzone;if("v"==i.rail.drag.ck){if(q>t&&.3*q>=s)return i.rail.drag=!1,!0;s>t&&(i.rail.drag.dl="f",g("body").scrollTop(g("body").scrollTop()))}else if("h"==i.rail.drag.ck){if(s>t&&.3*s>=q)return i.rail.drag=!1,!0;q>t&&(i.rail.drag.dl="f",g("body").scrollLeft(g("body").scrollLeft()))}}if(i.synched("touchmove",function(){i.rail.drag&&2==i.rail.drag.pt&&(i.prepareTransition&&i.prepareTransition(0),i.rail.scrollable&&i.setScrollTop(n),i.scrollmom.update(l,j),i.railh&&i.railh.scrollable?(i.setScrollLeft(o),i.showCursor(n,o)):i.showCursor(n),r.isie10&&document.selection.clear())}),r.ischrome&&i.istouchcapable&&(p=!1),p)return i.cancelEvent(a)}else if(1==i.rail.drag.pt)return i.onmousemove(a)}}if(i.onmousedown=function(a,b){if(!i.rail.drag||1==i.rail.drag.pt){if(i.railslocked)return i.cancelEvent(a);i.cancelScroll(),i.rail.drag={x:a.clientX,y:a.clientY,sx:i.scroll.x,sy:i.scroll.y,pt:1,hr:!!b};var c=i.getTarget(a);return!i.ispage&&r.hasmousecapture&&c.setCapture(),i.isiframe&&!r.hasmousecapture&&(i.saved.csspointerevents=i.doc.css("pointer-events"),i.css(i.doc,{"pointer-events":"none"})),i.hasmoving=!1,i.cancelEvent(a)}},i.onmouseup=function(a){return i.rail.drag?1!=i.rail.drag.pt?!0:(r.hasmousecapture&&document.releaseCapture(),i.isiframe&&!r.hasmousecapture&&i.doc.css("pointer-events",i.saved.csspointerevents),i.rail.drag=!1,i.hasmoving&&i.triggerScrollEnd(),i.cancelEvent(a)):void 0},i.onmousemove=function(a){if(i.rail.drag){if(1!=i.rail.drag.pt)return;if(r.ischrome&&0==a.which)return i.onmouseup(a);if(i.cursorfreezed=!0,i.hasmoving=!0,i.rail.drag.hr){i.scroll.x=i.rail.drag.sx+(a.clientX-i.rail.drag.x),i.scroll.x<0&&(i.scroll.x=0);var b=i.scrollvaluemaxw;i.scroll.x>b&&(i.scroll.x=b)}else{i.scroll.y=i.rail.drag.sy+(a.clientY-i.rail.drag.y),i.scroll.y<0&&(i.scroll.y=0);var c=i.scrollvaluemax;i.scroll.y>c&&(i.scroll.y=c)}return i.synched("mousemove",function(){i.rail.drag&&1==i.rail.drag.pt&&(i.showCursor(),i.rail.drag.hr?i.hasreversehr?i.doScrollLeft(i.scrollvaluemaxw-Math.round(i.scroll.x*i.scrollratio.x),i.opt.cursordragspeed):i.doScrollLeft(Math.round(i.scroll.x*i.scrollratio.x),i.opt.cursordragspeed):i.doScrollTop(Math.round(i.scroll.y*i.scrollratio.y),i.opt.cursordragspeed))}),i.cancelEvent(a)}i.checkarea=0},r.cantouch||i.opt.touchbehavior)i.onpreventclick=function(a){return i.preventclick?(i.preventclick.tg.onclick=i.preventclick.click,i.preventclick=!1,i.cancelEvent(a)):void 0},i.bind(i.win,"mousedown",i.ontouchstart),i.onclick=r.isios?!1:function(a){return i.lastmouseup?(i.lastmouseup=!1,i.cancelEvent(a)):!0},i.opt.grabcursorenabled&&r.cursorgrabvalue&&(i.css(i.ispage?i.doc:i.win,{cursor:r.cursorgrabvalue}),i.css(i.rail,{cursor:r.cursorgrabvalue}));else{var A=function(a){if(i.selectiondrag){if(a){var b=i.win.outerHeight(),c=a.pageY-i.selectiondrag.top;c>0&&b>c&&(c=0),c>=b&&(c-=b),i.selectiondrag.df=c}if(0!=i.selectiondrag.df){var d=2*-Math.floor(i.selectiondrag.df/6);i.doScrollBy(d),i.debounced("doselectionscroll",function(){A()},50)}}};"getSelection"in document?i.hasTextSelected=function(){return document.getSelection().rangeCount>0}:"selection"in document?i.hasTextSelected=function(){return"None"!=document.selection.type}:i.hasTextSelected=function(){return!1},i.onselectionstart=function(a){i.ispage||(i.selectiondrag=i.win.offset())},i.onselectionend=function(a){i.selectiondrag=!1},i.onselectiondrag=function(a){i.selectiondrag&&i.hasTextSelected()&&i.debounced("selectionscroll",function(){A(a)},250)}}r.hasw3ctouch?(i.css(i.rail,{"touch-action":"none"}),i.css(i.cursor,{"touch-action":"none"}),i.bind(i.win,"pointerdown",i.ontouchstart),i.bind(document,"pointerup",i.ontouchend),i.bind(document,"pointermove",i.ontouchmove)):r.hasmstouch?(i.css(i.rail,{"-ms-touch-action":"none"}),i.css(i.cursor,{"-ms-touch-action":"none"}),i.bind(i.win,"MSPointerDown",i.ontouchstart),i.bind(document,"MSPointerUp",i.ontouchend),i.bind(document,"MSPointerMove",i.ontouchmove),i.bind(i.cursor,"MSGestureHold",function(a){a.preventDefault()}),i.bind(i.cursor,"contextmenu",function(a){a.preventDefault()})):this.istouchcapable&&(i.bind(i.win,"touchstart",i.ontouchstart),i.bind(document,"touchend",i.ontouchend),i.bind(document,"touchcancel",i.ontouchend),i.bind(document,"touchmove",i.ontouchmove)),(i.opt.cursordragontouch||!r.cantouch&&!i.opt.touchbehavior)&&(i.rail.css({cursor:"default"}),i.railh&&i.railh.css({cursor:"default"}),i.jqbind(i.rail,"mouseenter",function(){return i.ispage||i.win.is(":visible")?(i.canshowonmouseevent&&i.showCursor(),void(i.rail.active=!0)):!1}),i.jqbind(i.rail,"mouseleave",function(){i.rail.active=!1,i.rail.drag||i.hideCursor()}),i.opt.sensitiverail&&(i.bind(i.rail,"click",function(a){i.doRailClick(a,!1,!1)}),i.bind(i.rail,"dblclick",function(a){i.doRailClick(a,!0,!1)}),i.bind(i.cursor,"click",function(a){i.cancelEvent(a)}),i.bind(i.cursor,"dblclick",function(a){i.cancelEvent(a)})),i.railh&&(i.jqbind(i.railh,"mouseenter",function(){return i.ispage||i.win.is(":visible")?(i.canshowonmouseevent&&i.showCursor(),void(i.rail.active=!0)):!1}),i.jqbind(i.railh,"mouseleave",function(){i.rail.active=!1,i.rail.drag||i.hideCursor()}),i.opt.sensitiverail&&(i.bind(i.railh,"click",function(a){i.doRailClick(a,!1,!0)}),i.bind(i.railh,"dblclick",function(a){i.doRailClick(a,!0,!0)}),i.bind(i.cursorh,"click",function(a){i.cancelEvent(a)}),i.bind(i.cursorh,"dblclick",function(a){i.cancelEvent(a)})))),r.cantouch||i.opt.touchbehavior?(i.bind(r.hasmousecapture?i.win:document,"mouseup",i.ontouchend),i.bind(document,"mousemove",i.ontouchmove),i.onclick&&i.bind(document,"click",i.onclick),i.opt.cursordragontouch?(i.bind(i.cursor,"mousedown",i.onmousedown),i.bind(i.cursor,"mouseup",i.onmouseup),i.cursorh&&i.bind(i.cursorh,"mousedown",function(a){i.onmousedown(a,!0)}),i.cursorh&&i.bind(i.cursorh,"mouseup",i.onmouseup)):(i.bind(i.rail,"mousedown",function(a){a.preventDefault()}),i.railh&&i.bind(i.railh,"mousedown",function(a){a.preventDefault()}))):(i.bind(r.hasmousecapture?i.win:document,"mouseup",i.onmouseup),i.bind(document,"mousemove",i.onmousemove),i.onclick&&i.bind(document,"click",i.onclick), +i.bind(i.cursor,"mousedown",i.onmousedown),i.bind(i.cursor,"mouseup",i.onmouseup),i.railh&&(i.bind(i.cursorh,"mousedown",function(a){i.onmousedown(a,!0)}),i.bind(i.cursorh,"mouseup",i.onmouseup)),!i.ispage&&i.opt.enablescrollonselection&&(i.bind(i.win[0],"mousedown",i.onselectionstart),i.bind(document,"mouseup",i.onselectionend),i.bind(i.cursor,"mouseup",i.onselectionend),i.cursorh&&i.bind(i.cursorh,"mouseup",i.onselectionend),i.bind(document,"mousemove",i.onselectiondrag)),i.zoom&&(i.jqbind(i.zoom,"mouseenter",function(){i.canshowonmouseevent&&i.showCursor(),i.rail.active=!0}),i.jqbind(i.zoom,"mouseleave",function(){i.rail.active=!1,i.rail.drag||i.hideCursor()}))),i.opt.enablemousewheel&&(i.isiframe||i.mousewheel(r.isie&&i.ispage?document:i.win,i.onmousewheel),i.mousewheel(i.rail,i.onmousewheel),i.railh&&i.mousewheel(i.railh,i.onmousewheelhr)),i.ispage||r.cantouch||/HTML|^BODY/.test(i.win[0].nodeName)||(i.win.attr("tabindex")||i.win.attr({tabindex:d++}),i.jqbind(i.win,"focus",function(a){b=i.getTarget(a).id||!0,i.hasfocus=!0,i.canshowonmouseevent&&i.noticeCursor()}),i.jqbind(i.win,"blur",function(a){b=!1,i.hasfocus=!1}),i.jqbind(i.win,"mouseenter",function(a){c=i.getTarget(a).id||!0,i.hasmousefocus=!0,i.canshowonmouseevent&&i.noticeCursor()}),i.jqbind(i.win,"mouseleave",function(){c=!1,i.hasmousefocus=!1,i.rail.drag||i.hideCursor()}))}if(i.onkeypress=function(a){if(i.railslocked&&0==i.page.maxh)return!0;a=a?a:window.e;var d=i.getTarget(a);if(d&&/INPUT|TEXTAREA|SELECT|OPTION/.test(d.nodeName)){var e=d.getAttribute("type")||d.type||!1;if(!e||!/submit|button|cancel/i.tp)return!0}if(g(d).attr("contenteditable"))return!0;if(i.hasfocus||i.hasmousefocus&&!b||i.ispage&&!b&&!c){var f=a.keyCode;if(i.railslocked&&27!=f)return i.cancelEvent(a);var h=a.ctrlKey||!1,j=a.shiftKey||!1,k=!1;switch(f){case 38:case 63233:i.doScrollBy(72),k=!0;break;case 40:case 63235:i.doScrollBy(-72),k=!0;break;case 37:case 63232:i.railh&&(h?i.doScrollLeft(0):i.doScrollLeftBy(72),k=!0);break;case 39:case 63234:i.railh&&(h?i.doScrollLeft(i.page.maxw):i.doScrollLeftBy(-72),k=!0);break;case 33:case 63276:i.doScrollBy(i.view.h),k=!0;break;case 34:case 63277:i.doScrollBy(-i.view.h),k=!0;break;case 36:case 63273:i.railh&&h?i.doScrollPos(0,0):i.doScrollTo(0),k=!0;break;case 35:case 63275:i.railh&&h?i.doScrollPos(i.page.maxw,i.page.maxh):i.doScrollTo(i.page.maxh),k=!0;break;case 32:i.opt.spacebarenabled&&(j?i.doScrollBy(i.view.h):i.doScrollBy(-i.view.h),k=!0);break;case 27:i.zoomactive&&(i.doZoom(),k=!0)}if(k)return i.cancelEvent(a)}},i.opt.enablekeyboard&&i.bind(document,r.isopera&&!r.isopera12?"keypress":"keydown",i.onkeypress),i.bind(document,"keydown",function(a){var b=a.ctrlKey||!1;b&&(i.wheelprevented=!0)}),i.bind(document,"keyup",function(a){var b=a.ctrlKey||!1;b||(i.wheelprevented=!1)}),i.bind(window,"blur",function(a){i.wheelprevented=!1}),i.bind(window,"resize",i.lazyResize),i.bind(window,"orientationchange",i.lazyResize),i.bind(window,"load",i.lazyResize),r.ischrome&&!i.ispage&&!i.haswrapper){var B=i.win.attr("style"),C=parseFloat(i.win.css("width"))+1;i.win.css("width",C),i.synched("chromefix",function(){i.win.attr("style",B)})}i.onAttributeChange=function(a){i.lazyResize(i.isieold?250:30)},i.isie11||n===!1||(i.observerbody=new n(function(a){return a.forEach(function(a){return"attributes"==a.type?g("body").hasClass("modal-open")&&g("body").hasClass("modal-dialog")&&!g.contains(g(".modal-dialog")[0],i.doc[0])?i.hide():i.show():void 0}),i.me.clientWidth!=i.page.width||i.me.clientHeight!=i.page.height?i.lazyResize(30):void 0}),i.observerbody.observe(document.body,{childList:!0,subtree:!0,characterData:!1,attributes:!0,attributeFilter:["class"]})),i.ispage||i.haswrapper||(n!==!1?(i.observer=new n(function(a){a.forEach(i.onAttributeChange)}),i.observer.observe(i.win[0],{childList:!0,characterData:!1,attributes:!0,subtree:!1}),i.observerremover=new n(function(a){a.forEach(function(a){if(a.removedNodes.length>0)for(var b in a.removedNodes)if(i&&a.removedNodes[b]==i.win[0])return i.remove()})}),i.observerremover.observe(i.win[0].parentNode,{childList:!0,characterData:!1,attributes:!1,subtree:!1})):(i.bind(i.win,r.isie&&!r.isie9?"propertychange":"DOMAttrModified",i.onAttributeChange),r.isie9&&i.win[0].attachEvent("onpropertychange",i.onAttributeChange),i.bind(i.win,"DOMNodeRemoved",function(a){a.target==i.win[0]&&i.remove()}))),!i.ispage&&i.opt.boxzoom&&i.bind(window,"resize",i.resizeZoom),i.istextarea&&(i.bind(i.win,"keydown",i.lazyResize),i.bind(i.win,"mouseup",i.lazyResize)),i.lazyResize(30)}if("IFRAME"==this.doc[0].nodeName){var D=function(){i.iframexd=!1;var a;try{a="contentDocument"in this?this.contentDocument:this.contentWindow.document;a.domain}catch(c){i.iframexd=!0,a=!1}if(i.iframexd)return"console"in window&&console.log("NiceScroll error: policy restriced iframe"),!0;if(i.forcescreen=!0,i.isiframe&&(i.iframe={doc:g(a),html:i.doc.contents().find("html")[0],body:i.doc.contents().find("body")[0]},i.getContentSize=function(){return{w:Math.max(i.iframe.html.scrollWidth,i.iframe.body.scrollWidth),h:Math.max(i.iframe.html.scrollHeight,i.iframe.body.scrollHeight)}},i.docscroll=g(i.iframe.body)),!r.isios&&i.opt.iframeautoresize&&!i.isiframe){i.win.scrollTop(0),i.doc.height("");var d=Math.max(a.getElementsByTagName("html")[0].scrollHeight,a.body.scrollHeight);i.doc.height(d)}i.lazyResize(30),r.isie7&&i.css(g(i.iframe.html),e),i.css(g(i.iframe.body),e),r.isios&&i.haswrapper&&i.css(g(a.body),{"-webkit-transform":"translate3d(0,0,0)"}),"contentWindow"in this?i.bind(this.contentWindow,"scroll",i.onscroll):i.bind(a,"scroll",i.onscroll),i.opt.enablemousewheel&&i.mousewheel(a,i.onmousewheel),i.opt.enablekeyboard&&i.bind(a,r.isopera?"keypress":"keydown",i.onkeypress),(r.cantouch||i.opt.touchbehavior)&&(i.bind(a,"mousedown",i.ontouchstart),i.bind(a,"mousemove",function(a){return i.ontouchmove(a,!0)}),i.opt.grabcursorenabled&&r.cursorgrabvalue&&i.css(g(a.body),{cursor:r.cursorgrabvalue})),i.bind(a,"mouseup",i.ontouchend),i.zoom&&(i.opt.dblclickzoom&&i.bind(a,"dblclick",i.doZoom),i.ongesturezoom&&i.bind(a,"gestureend",i.ongesturezoom))};this.doc[0].readyState&&"complete"==this.doc[0].readyState&&setTimeout(function(){D.call(i.doc[0],!1)},500),i.bind(this.doc,"load",D)}},this.showCursor=function(a,b){if(i.cursortimeout&&(clearTimeout(i.cursortimeout),i.cursortimeout=0),i.rail){if(i.autohidedom&&(i.autohidedom.stop().css({opacity:i.opt.cursoropacitymax}),i.cursoractive=!0),i.rail.drag&&1==i.rail.drag.pt||(void 0!==a&&a!==!1&&(i.scroll.y=Math.round(1*a/i.scrollratio.y)),void 0!==b&&(i.scroll.x=Math.round(1*b/i.scrollratio.x))),i.cursor.css({height:i.cursorheight,top:i.scroll.y}),i.cursorh){var c=i.hasreversehr?i.scrollvaluemaxw-i.scroll.x:i.scroll.x;!i.rail.align&&i.rail.visibility?i.cursorh.css({width:i.cursorwidth,left:c+i.rail.width}):i.cursorh.css({width:i.cursorwidth,left:c}),i.cursoractive=!0}i.zoom&&i.zoom.stop().css({opacity:i.opt.cursoropacitymax})}},this.hideCursor=function(a){i.cursortimeout||i.rail&&i.autohidedom&&(i.hasmousefocus&&"leave"==i.opt.autohidemode||(i.cursortimeout=setTimeout(function(){i.rail.active&&i.showonmouseevent||(i.autohidedom.stop().animate({opacity:i.opt.cursoropacitymin}),i.zoom&&i.zoom.stop().animate({opacity:i.opt.cursoropacitymin}),i.cursoractive=!1),i.cursortimeout=0},a||i.opt.hidecursordelay)))},this.noticeCursor=function(a,b,c){i.showCursor(b,c),i.rail.active||i.hideCursor(a)},this.getContentSize=i.ispage?function(){return{w:Math.max(document.body.scrollWidth,document.documentElement.scrollWidth),h:Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)}}:i.haswrapper?function(){return{w:i.doc.outerWidth()+parseInt(i.win.css("paddingLeft"))+parseInt(i.win.css("paddingRight")),h:i.doc.outerHeight()+parseInt(i.win.css("paddingTop"))+parseInt(i.win.css("paddingBottom"))}}:function(){return{w:i.docscroll[0].scrollWidth,h:i.docscroll[0].scrollHeight}},this.onResize=function(a,b){if(!i||!i.win)return!1;if(!i.haswrapper&&!i.ispage){if("none"==i.win.css("display"))return i.visibility&&i.hideRail().hideRailHr(),!1;i.hidden||i.visibility||i.showRail().showRailHr()}var c=i.page.maxh,d=i.page.maxw,e={h:i.view.h,w:i.view.w};if(i.view={w:i.ispage?i.win.width():parseInt(i.win[0].clientWidth),h:i.ispage?i.win.height():parseInt(i.win[0].clientHeight)},i.page=b?b:i.getContentSize(),i.page.maxh=Math.max(0,i.page.h-i.view.h),i.page.maxw=Math.max(0,i.page.w-i.view.w),i.page.maxh==c&&i.page.maxw==d&&i.view.w==e.w&&i.view.h==e.h){if(i.ispage)return i;var f=i.win.offset();if(i.lastposition){var g=i.lastposition;if(g.top==f.top&&g.left==f.left)return i}i.lastposition=f}if(0==i.page.maxh?(i.hideRail(),i.scrollvaluemax=0,i.scroll.y=0,i.scrollratio.y=0,i.cursorheight=0,i.setScrollTop(0),i.rail&&(i.rail.scrollable=!1)):(i.page.maxh-=i.opt.railpadding.top+i.opt.railpadding.bottom,i.rail.scrollable=!0),0==i.page.maxw?(i.hideRailHr(),i.scrollvaluemaxw=0,i.scroll.x=0,i.scrollratio.x=0,i.cursorwidth=0,i.setScrollLeft(0),i.railh&&(i.railh.scrollable=!1)):(i.page.maxw-=i.opt.railpadding.left+i.opt.railpadding.right,i.railh&&(i.railh.scrollable=i.opt.horizrailenabled)),i.railslocked=i.locked||0==i.page.maxh&&0==i.page.maxw,i.railslocked)return i.ispage||i.updateScrollBar(i.view),!1;i.hidden||i.visibility?!i.railh||i.hidden||i.railh.visibility||i.showRailHr():i.showRail().showRailHr(),i.istextarea&&i.win.css("resize")&&"none"!=i.win.css("resize")&&(i.view.h-=20),i.cursorheight=Math.min(i.view.h,Math.round(i.view.h*(i.view.h/i.page.h))),i.cursorheight=i.opt.cursorfixedheight?i.opt.cursorfixedheight:Math.max(i.opt.cursorminheight,i.cursorheight),i.cursorwidth=Math.min(i.view.w,Math.round(i.view.w*(i.view.w/i.page.w))),i.cursorwidth=i.opt.cursorfixedheight?i.opt.cursorfixedheight:Math.max(i.opt.cursorminheight,i.cursorwidth),i.scrollvaluemax=i.view.h-i.cursorheight-i.cursor.hborder-(i.opt.railpadding.top+i.opt.railpadding.bottom),i.railh&&(i.railh.width=i.page.maxh>0?i.view.w-i.rail.width:i.view.w,i.scrollvaluemaxw=i.railh.width-i.cursorwidth-i.cursorh.wborder-(i.opt.railpadding.left+i.opt.railpadding.right)),i.ispage||i.updateScrollBar(i.view),i.scrollratio={x:i.page.maxw/i.scrollvaluemaxw,y:i.page.maxh/i.scrollvaluemax};var h=i.getScrollTop();return h>i.page.maxh?i.doScrollTop(i.page.maxh):(i.scroll.y=Math.round(i.getScrollTop()*(1/i.scrollratio.y)),i.scroll.x=Math.round(i.getScrollLeft()*(1/i.scrollratio.x)),i.cursoractive&&i.noticeCursor()),i.scroll.y&&0==i.getScrollTop()&&i.doScrollTo(Math.floor(i.scroll.y*i.scrollratio.y)),i},this.resize=i.onResize,this.hlazyresize=0,this.lazyResize=function(a){return i.haswrapper||i.hide(),i.hlazyresize&&clearTimeout(i.hlazyresize),i.hlazyresize=setTimeout(function(){i&&i.show().resize()},240),i},this.jqbind=function(a,b,c){i.events.push({e:a,n:b,f:c,q:!0}),g(a).bind(b,c)},this.mousewheel=function(a,b,c){var d="jquery"in a?a[0]:a;if("onwheel"in document.createElement("div"))i._bind(d,"wheel",b,c||!1);else{var e=void 0!==document.onmousewheel?"mousewheel":"DOMMouseScroll";A(d,e,b,c||!1),"DOMMouseScroll"==e&&A(d,"MozMousePixelScroll",b,c||!1)}},r.haseventlistener?(this.bind=function(a,b,c,d){var e="jquery"in a?a[0]:a;i._bind(e,b,c,d||!1)},this._bind=function(a,b,c,d){i.events.push({e:a,n:b,f:c,b:d,q:!1}),a.addEventListener(b,c,d||!1)},this.cancelEvent=function(a){if(!a)return!1;var a=a.original?a.original:a;return a.cancelable&&a.preventDefault(),a.stopPropagation(),a.preventManipulation&&a.preventManipulation(),!1},this.stopPropagation=function(a){if(!a)return!1;var a=a.original?a.original:a;return a.stopPropagation(),!1},this._unbind=function(a,b,c,d){a.removeEventListener(b,c,d)}):(this.bind=function(a,b,c,d){var e="jquery"in a?a[0]:a;i._bind(e,b,function(a){return a=a||window.event||!1,a&&a.srcElement&&(a.target=a.srcElement),"pageY"in a||(a.pageX=a.clientX+document.documentElement.scrollLeft,a.pageY=a.clientY+document.documentElement.scrollTop),c.call(e,a)===!1||d===!1?i.cancelEvent(a):!0})},this._bind=function(a,b,c,d){i.events.push({e:a,n:b,f:c,b:d,q:!1}),a.attachEvent?a.attachEvent("on"+b,c):a["on"+b]=c},this.cancelEvent=function(a){var a=window.event||!1;return a?(a.cancelBubble=!0,a.cancel=!0,a.returnValue=!1,!1):!1},this.stopPropagation=function(a){var a=window.event||!1;return a?(a.cancelBubble=!0,!1):!1},this._unbind=function(a,b,c,d){a.detachEvent?a.detachEvent("on"+b,c):a["on"+b]=!1}),this.unbindAll=function(){for(var a=0;a0)return c;b=b.parentNode?b.parentNode:!1}return!1},this.triggerScrollEnd=function(){if(i.onscrollend){var a=i.getScrollLeft(),b=i.getScrollTop(),c={type:"scrollend",current:{x:a,y:b},end:{x:a,y:b}};i.onscrollend.call(i,c)}},this.onmousewheel=function(a){if(!i.wheelprevented){if(i.railslocked)return i.debounced("checkunlock",i.resize,250),!0;if(i.rail.drag)return i.cancelEvent(a);if("auto"==i.opt.oneaxismousemode&&0!=a.deltaX&&(i.opt.oneaxismousemode=!1),i.opt.oneaxismousemode&&0==a.deltaX&&!i.rail.scrollable)return i.railh&&i.railh.scrollable?i.onmousewheelhr(a):!0;var b=+new Date,c=!1;if(i.opt.preservenativescrolling&&i.checkarea+60020?c:0},i.opt.smoothscroll?i.ishwscroll&&r.hastransition&&i.opt.usetransition&&i.opt.smoothscroll?(this.prepareTransition=function(a,b){var c=b?a>20?a:0:i.getTransitionSpeed(a),d=c?r.prefixstyle+"transform "+c+"ms ease-out":"";return i.lasttransitionstyle&&i.lasttransitionstyle==d||(i.lasttransitionstyle=d,i.doc.css(r.transitionstyle,d)),c},this.doScrollLeft=function(a,b){var c=i.scrollrunning?i.newscrolly:i.getScrollTop();i.doScrollPos(a,c,b)},this.doScrollTop=function(a,b){var c=i.scrollrunning?i.newscrollx:i.getScrollLeft();i.doScrollPos(c,a,b)},this.doScrollPos=function(a,b,c){var d=i.getScrollTop(),e=i.getScrollLeft();return((i.newscrolly-d)*(b-d)<0||(i.newscrollx-e)*(a-e)<0)&&i.cancelScroll(),0==i.opt.bouncescroll&&(0>b?b=0:b>i.page.maxh&&(b=i.page.maxh),0>a?a=0:a>i.page.maxw&&(a=i.page.maxw)),i.scrollrunning&&a==i.newscrollx&&b==i.newscrolly?!1:(i.newscrolly=b,i.newscrollx=a,i.newscrollspeed=c||!1,i.timer?!1:void(i.timer=setTimeout(function(){var c=i.getScrollTop(),d=i.getScrollLeft(),e={};e.x=a-d,e.y=b-c,e.px=d,e.py=c;var f=Math.round(Math.sqrt(Math.pow(e.x,2)+Math.pow(e.y,2))),g=i.newscrollspeed&&i.newscrollspeed>1?i.newscrollspeed:i.getTransitionSpeed(f);if(i.newscrollspeed&&i.newscrollspeed<=1&&(g*=i.newscrollspeed),i.prepareTransition(g,!0),i.timerscroll&&i.timerscroll.tm&&clearInterval(i.timerscroll.tm),g>0){if(!i.scrollrunning&&i.onscrollstart){var h={type:"scrollstart",current:{x:d,y:c},request:{x:a,y:b},end:{x:i.newscrollx,y:i.newscrolly},speed:g};i.onscrollstart.call(i,h)}r.transitionend?i.scrollendtrapped||(i.scrollendtrapped=!0,i.bind(i.doc,r.transitionend,i.onScrollTransitionEnd,!1)):(i.scrollendtrapped&&clearTimeout(i.scrollendtrapped),i.scrollendtrapped=setTimeout(i.onScrollTransitionEnd,g));var j=c,k=d;i.timerscroll={bz:new u(j,i.newscrolly,g,0,0,.58,1),bh:new u(k,i.newscrollx,g,0,0,.58,1)},i.cursorfreezed||(i.timerscroll.tm=setInterval(function(){i.showCursor(i.getScrollTop(),i.getScrollLeft())},60))}i.synched("doScroll-set",function(){i.timer=0,i.scrollendtrapped&&(i.scrollrunning=!0),i.setScrollTop(i.newscrolly),i.setScrollLeft(i.newscrollx),i.scrollendtrapped||i.onScrollTransitionEnd()})},50)))},this.cancelScroll=function(){if(!i.scrollendtrapped)return!0;var a=i.getScrollTop(),b=i.getScrollLeft();return i.scrollrunning=!1,r.transitionend||clearTimeout(r.transitionend),i.scrollendtrapped=!1,i._unbind(i.doc[0],r.transitionend,i.onScrollTransitionEnd),i.prepareTransition(0),i.setScrollTop(a),i.railh&&i.setScrollLeft(b),i.timerscroll&&i.timerscroll.tm&&clearInterval(i.timerscroll.tm),i.timerscroll=!1,i.cursorfreezed=!1,i.showCursor(a,b),i},this.onScrollTransitionEnd=function(){i.scrollendtrapped&&i._unbind(i.doc[0],r.transitionend,i.onScrollTransitionEnd),i.scrollendtrapped=!1,i.prepareTransition(0),i.timerscroll&&i.timerscroll.tm&&clearInterval(i.timerscroll.tm),i.timerscroll=!1;var a=i.getScrollTop(),b=i.getScrollLeft();return i.setScrollTop(a),i.railh&&i.setScrollLeft(b),i.noticeCursor(!1,a,b),i.cursorfreezed=!1,0>a?a=0:a>i.page.maxh&&(a=i.page.maxh),0>b?b=0:b>i.page.maxw&&(b=i.page.maxw),a!=i.newscrolly||b!=i.newscrollx?i.doScrollPos(b,a,i.opt.snapbackspeed):(i.onscrollend&&i.scrollrunning&&i.triggerScrollEnd(),void(i.scrollrunning=!1))}):(this.doScrollLeft=function(a,b){var c=i.scrollrunning?i.newscrolly:i.getScrollTop();i.doScrollPos(a,c,b)},this.doScrollTop=function(a,b){var c=i.scrollrunning?i.newscrollx:i.getScrollLeft();i.doScrollPos(c,a,b)},this.doScrollPos=function(a,b,c){function n(){if(i.cancelAnimationFrame)return!0;if(i.scrollrunning=!0,m=1-m)return i.timer=j(n)||1;var b,c,a=0,d=c=i.getScrollTop();if(i.dst.ay){d=i.bzscroll?i.dst.py+i.bzscroll.getNow()*i.dst.ay:i.newscrolly;var e=d-c;(0>e&&d0&&d>i.newscrolly)&&(d=i.newscrolly),i.setScrollTop(d),d==i.newscrolly&&(a=1)}else a=1;var f=b=i.getScrollLeft();if(i.dst.ax){f=i.bzscroll?i.dst.px+i.bzscroll.getNow()*i.dst.ax:i.newscrollx;var e=f-b;(0>e&&f0&&f>i.newscrollx)&&(f=i.newscrollx),i.setScrollLeft(f),f==i.newscrollx&&(a+=1)}else a+=1;2==a?(i.timer=0,i.cursorfreezed=!1,i.bzscroll=!1,i.scrollrunning=!1,0>d?d=0:d>i.page.maxh&&(d=Math.max(0,i.page.maxh)),0>f?f=0:f>i.page.maxw&&(f=i.page.maxw),f!=i.newscrollx||d!=i.newscrolly?i.doScrollPos(f,d):i.onscrollend&&i.triggerScrollEnd()):i.timer=j(n)||1}var b=void 0===b||b===!1?i.getScrollTop(!0):b;if(i.timer&&i.newscrolly==b&&i.newscrollx==a)return!0;i.timer&&k(i.timer),i.timer=0;var d=i.getScrollTop(),e=i.getScrollLeft();((i.newscrolly-d)*(b-d)<0||(i.newscrollx-e)*(a-e)<0)&&i.cancelScroll(),i.newscrolly=b,i.newscrollx=a,i.bouncescroll&&i.rail.visibility||(i.newscrolly<0?i.newscrolly=0:i.newscrolly>i.page.maxh&&(i.newscrolly=i.page.maxh)),i.bouncescroll&&i.railh.visibility||(i.newscrollx<0?i.newscrollx=0:i.newscrollx>i.page.maxw&&(i.newscrollx=i.page.maxw)),i.dst={},i.dst.x=a-e,i.dst.y=b-d,i.dst.px=e,i.dst.py=d;var f=Math.round(Math.sqrt(Math.pow(i.dst.x,2)+Math.pow(i.dst.y,2)));i.dst.ax=i.dst.x/f,i.dst.ay=i.dst.y/f;var g=0,h=f;0==i.dst.x?(g=d,h=b,i.dst.ay=1,i.dst.py=0):0==i.dst.y&&(g=e,h=a,i.dst.ax=1,i.dst.px=0);var l=i.getTransitionSpeed(f);if(c&&1>=c&&(l*=c),l>0?i.bzscroll=i.bzscroll?i.bzscroll.update(h,l):new u(g,h,l,0,1,0,1):i.bzscroll=!1,!i.timer){(d==i.page.maxh&&b>=i.page.maxh||e==i.page.maxw&&a>=i.page.maxw)&&i.checkContentSize();var m=1;if(i.cancelAnimationFrame=!1,i.timer=1,i.onscrollstart&&!i.scrollrunning){var o={type:"scrollstart",current:{x:e,y:d},request:{x:a,y:b},end:{x:i.newscrollx,y:i.newscrolly},speed:l};i.onscrollstart.call(i,o)}n(),(d==i.page.maxh&&b>=d||e==i.page.maxw&&a>=e)&&i.checkContentSize(),i.noticeCursor()}},this.cancelScroll=function(){return i.timer&&k(i.timer),i.timer=0,i.bzscroll=!1,i.scrollrunning=!1,i}):(this.doScrollLeft=function(a,b){var c=i.getScrollTop();i.doScrollPos(a,c,b)},this.doScrollTop=function(a,b){var c=i.getScrollLeft();i.doScrollPos(c,a,b)},this.doScrollPos=function(a,b,c){var d=a>i.page.maxw?i.page.maxw:a;0>d&&(d=0);var e=b>i.page.maxh?i.page.maxh:b;0>e&&(e=0),i.synched("scroll",function(){i.setScrollTop(e),i.setScrollLeft(d)})},this.cancelScroll=function(){}),this.doScrollBy=function(a,b){var c=0;if(b)c=Math.floor((i.scroll.y-a)*i.scrollratio.y);else{var d=i.timer?i.newscrolly:i.getScrollTop(!0);c=d-a}if(i.bouncescroll){var e=Math.round(i.view.h/2);-e>c?c=-e:c>i.page.maxh+e&&(c=i.page.maxh+e)}i.cursorfreezed=!1;var f=i.getScrollTop(!0);return 0>c&&0>=f?i.noticeCursor():c>i.page.maxh&&f>=i.page.maxh?(i.checkContentSize(),i.noticeCursor()):void i.doScrollTop(c)},this.doScrollLeftBy=function(a,b){var c=0;if(b)c=Math.floor((i.scroll.x-a)*i.scrollratio.x);else{var d=i.timer?i.newscrollx:i.getScrollLeft(!0);c=d-a}if(i.bouncescroll){var e=Math.round(i.view.w/2);-e>c?c=-e:c>i.page.maxw+e&&(c=i.page.maxw+e)}i.cursorfreezed=!1;var f=i.getScrollLeft(!0);return 0>c&&0>=f?i.noticeCursor():c>i.page.maxw&&f>=i.page.maxw?i.noticeCursor():void i.doScrollLeft(c)},this.doScrollTo=function(a,b){var c=b?Math.round(a*i.scrollratio.y):a;0>c?c=0:c>i.page.maxh&&(c=i.page.maxh),i.cursorfreezed=!1,i.doScrollTop(a)},this.checkContentSize=function(){var a=i.getContentSize();(a.h!=i.page.h||a.w!=i.page.w)&&i.resize(!1,a)},i.onscroll=function(a){i.rail.drag||i.cursorfreezed||i.synched("scroll",function(){i.scroll.y=Math.round(i.getScrollTop()*(1/i.scrollratio.y)),i.railh&&(i.scroll.x=Math.round(i.getScrollLeft()*(1/i.scrollratio.x))),i.noticeCursor()})},i.bind(i.docscroll,"scroll",i.onscroll),this.doZoomIn=function(a){if(!i.zoomactive){i.zoomactive=!0,i.zoomrestore={style:{}};var b=["position","top","left","zIndex","backgroundColor","marginTop","marginBottom","marginLeft","marginRight"],c=i.win[0].style;for(var d in b){var e=b[d];i.zoomrestore.style[e]=void 0!==c[e]?c[e]:""}i.zoomrestore.style.width=i.win.css("width"),i.zoomrestore.style.height=i.win.css("height"),i.zoomrestore.padding={w:i.win.outerWidth()-i.win.width(),h:i.win.outerHeight()-i.win.height()},r.isios4&&(i.zoomrestore.scrollTop=g(window).scrollTop(),g(window).scrollTop(0)),i.win.css({position:r.isios4?"absolute":"fixed",top:0,left:0,zIndex:f+100,margin:0});var h=i.win.css("backgroundColor");return(""==h||/transparent|rgba\(0, 0, 0, 0\)|rgba\(0,0,0,0\)/.test(h))&&i.win.css("backgroundColor","#fff"),i.rail.css({zIndex:f+101}),i.zoom.css({zIndex:f+102}),i.zoom.css("backgroundPosition","0px -18px"),i.resizeZoom(),i.onzoomin&&i.onzoomin.call(i),i.cancelEvent(a)}},this.doZoomOut=function(a){return i.zoomactive?(i.zoomactive=!1,i.win.css("margin",""),i.win.css(i.zoomrestore.style),r.isios4&&g(window).scrollTop(i.zoomrestore.scrollTop),i.rail.css({"z-index":i.zindex}),i.zoom.css({"z-index":i.zindex}),i.zoomrestore=!1,i.zoom.css("backgroundPosition","0px 0px"),i.onResize(),i.onzoomout&&i.onzoomout.call(i),i.cancelEvent(a)):void 0},this.doZoom=function(a){return i.zoomactive?i.doZoomOut(a):i.doZoomIn(a)},this.resizeZoom=function(){if(i.zoomactive){var a=i.getScrollTop();i.win.css({width:g(window).width()-i.zoomrestore.padding.w+"px",height:g(window).height()-i.zoomrestore.padding.h+"px"}),i.onResize(),i.setScrollTop(Math.min(i.page.maxh,a))}},this.init(),g.nicescroll.push(this)},s=function(a){var b=this;this.nc=a,this.lastx=0,this.lasty=0,this.speedx=0,this.speedy=0,this.lasttime=0,this.steptime=0,this.snapx=!1,this.snapy=!1,this.demulx=0,this.demuly=0,this.lastscrollx=-1,this.lastscrolly=-1,this.chkx=0,this.chky=0,this.timer=0,this.time=function(){return+new Date},this.reset=function(a,c){b.stop();var d=b.time();b.steptime=0,b.lasttime=d,b.speedx=0,b.speedy=0,b.lastx=a,b.lasty=c,b.lastscrollx=-1,b.lastscrolly=-1},this.update=function(a,c){var d=b.time();b.steptime=d-b.lasttime,b.lasttime=d;var e=c-b.lasty,f=a-b.lastx,g=b.nc.getScrollTop(),h=b.nc.getScrollLeft(),i=g+e,j=h+f;b.snapx=0>j||j>b.nc.page.maxw,b.snapy=0>i||i>b.nc.page.maxh,b.speedx=f,b.speedy=e,b.lastx=a,b.lasty=c},this.stop=function(){b.nc.unsynched("domomentum2d"),b.timer&&clearTimeout(b.timer),b.timer=0,b.lastscrollx=-1,b.lastscrolly=-1},this.doSnapy=function(a,c){var d=!1;0>c?(c=0,d=!0):c>b.nc.page.maxh&&(c=b.nc.page.maxh,d=!0),0>a?(a=0,d=!0):a>b.nc.page.maxw&&(a=b.nc.page.maxw,d=!0),d?b.nc.doScrollPos(a,c,b.nc.opt.snapbackspeed):b.nc.triggerScrollEnd()},this.doMomentum=function(a){var c=b.time(),d=a?c+a:b.lasttime,e=b.nc.getScrollLeft(),f=b.nc.getScrollTop(),g=b.nc.page.maxh,h=b.nc.page.maxw;b.speedx=h>0?Math.min(60,b.speedx):0,b.speedy=g>0?Math.min(60,b.speedy):0;var i=d&&60>=c-d;(0>f||f>g||0>e||e>h)&&(i=!1);var j=b.speedy&&i?b.speedy:!1,k=b.speedx&&i?b.speedx:!1;if(j||k){var l=Math.max(16,b.steptime);if(l>50){var m=l/50;b.speedx*=m,b.speedy*=m,l=50}b.demulxy=0,b.lastscrollx=b.nc.getScrollLeft(),b.chkx=b.lastscrollx,b.lastscrolly=b.nc.getScrollTop(),b.chky=b.lastscrolly;var n=b.lastscrollx,o=b.lastscrolly,p=function(){var a=b.time()-c>600?.04:.02;b.speedx&&(n=Math.floor(b.lastscrollx-b.speedx*(1-b.demulxy)),b.lastscrollx=n,(0>n||n>h)&&(a=.1)),b.speedy&&(o=Math.floor(b.lastscrolly-b.speedy*(1-b.demulxy)),b.lastscrolly=o,(0>o||o>g)&&(a=.1)),b.demulxy=Math.min(1,b.demulxy+a),b.nc.synched("domomentum2d",function(){if(b.speedx){b.nc.getScrollLeft();b.chkx=n,b.nc.setScrollLeft(n)}if(b.speedy){b.nc.getScrollTop();b.chky=o,b.nc.setScrollTop(o)}b.timer||(b.nc.hideCursor(),b.doSnapy(n,o))}),b.demulxy<1?b.timer=setTimeout(p,l):(b.stop(),b.nc.hideCursor(),b.doSnapy(n,o))};p()}else b.doSnapy(b.nc.getScrollLeft(),b.nc.getScrollTop())}},t=a.fn.scrollTop;a.cssHooks.pageYOffset={get:function(a,b,c){var d=g.data(a,"__nicescroll")||!1;return d&&d.ishwscroll?d.getScrollTop():t.call(a)},set:function(a,b){var c=g.data(a,"__nicescroll")||!1;return c&&c.ishwscroll?c.setScrollTop(parseInt(b)):t.call(a,b),this}},a.fn.scrollTop=function(a){if(void 0===a){var b=this[0]?g.data(this[0],"__nicescroll")||!1:!1;return b&&b.ishwscroll?b.getScrollTop():t.call(this)}return this.each(function(){var b=g.data(this,"__nicescroll")||!1;b&&b.ishwscroll?b.setScrollTop(parseInt(a)):t.call(g(this),a)})};var u=a.fn.scrollLeft;g.cssHooks.pageXOffset={get:function(a,b,c){var d=g.data(a,"__nicescroll")||!1;return d&&d.ishwscroll?d.getScrollLeft():u.call(a)},set:function(a,b){var c=g.data(a,"__nicescroll")||!1;return c&&c.ishwscroll?c.setScrollLeft(parseInt(b)):u.call(a,b),this}},a.fn.scrollLeft=function(a){if(void 0===a){var b=this[0]?g.data(this[0],"__nicescroll")||!1:!1;return b&&b.ishwscroll?b.getScrollLeft():u.call(this)}return this.each(function(){var b=g.data(this,"__nicescroll")||!1;b&&b.ishwscroll?b.setScrollLeft(parseInt(a)):u.call(g(this),a)})};var v=function(a){var b=this;if(this.length=0,this.name="nicescrollarray",this.each=function(a){return g.each(b,a),b},this.push=function(a){b[b.length]=a,b.length++},this.eq=function(a){return b[a]},a)for(var c=0;c b; b++) if (b in this && this[b] === a) return b; return -1 }; for (u = { catchupTime: 100, initialRate: .03, minTime: 250, ghostTime: 100, maxProgressPerFrame: 20, easeFactor: 1.25, startOnPageLoad: !0, restartOnPushState: !0, restartOnRequestAfter: 500, target: "body", elements: { checkInterval: 100, selectors: ["body"] }, eventLag: { minSamples: 10, sampleCount: 3, lagThreshold: 3 }, ajax: { trackMethods: ["GET"], trackWebSockets: !0, ignoreURLs: [] } }, C = function () { var a; return null != (a = "undefined" != typeof performance && null !== performance && "function" == typeof performance.now ? performance.now() : void 0) ? a : +new Date }, E = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame, t = window.cancelAnimationFrame || window.mozCancelAnimationFrame, null == E && (E = function (a) { return setTimeout(a, 50) }, t = function (a) { return clearTimeout(a) }), G = function (a) { var b, c; return b = C(), (c = function () { var d; return d = C() - b, d >= 33 ? (b = C(), a(d, function () { return E(c) })) : setTimeout(c, 33 - d) })() }, F = function () { var a, b, c; return c = arguments[0], b = arguments[1], a = 3 <= arguments.length ? X.call(arguments, 2) : [], "function" == typeof c[b] ? c[b].apply(c, a) : c[b] }, v = function () { var a, b, c, d, e, f, g; for (b = arguments[0], d = 2 <= arguments.length ? X.call(arguments, 1) : [], f = 0, g = d.length; g > f; f++) if (c = d[f]) for (a in c) Y.call(c, a) && (e = c[a], null != b[a] && "object" == typeof b[a] && null != e && "object" == typeof e ? v(b[a], e) : b[a] = e); return b }, q = function (a) { var b, c, d, e, f; for (c = b = 0, e = 0, f = a.length; f > e; e++) d = a[e], c += Math.abs(d), b++; return c / b }, x = function (a, b) { var c, d, e; if (null == a && (a = "options"), null == b && (b = !0), e = document.querySelector("[data-pace-" + a + "]")) { if (c = e.getAttribute("data-pace-" + a), !b) return c; try { return JSON.parse(c) } catch (f) { return d = f, "undefined" != typeof console && null !== console ? console.error("Error parsing inline pace options", d) : void 0 } } }, g = function () { function a() { } return a.prototype.on = function (a, b, c, d) { var e; return null == d && (d = !1), null == this.bindings && (this.bindings = {}), null == (e = this.bindings)[a] && (e[a] = []), this.bindings[a].push({ handler: b, ctx: c, once: d }) }, a.prototype.once = function (a, b, c) { return this.on(a, b, c, !0) }, a.prototype.off = function (a, b) { var c, d, e; if (null != (null != (d = this.bindings) ? d[a] : void 0)) { if (null == b) return delete this.bindings[a]; for (c = 0, e = []; c < this.bindings[a].length;) e.push(this.bindings[a][c].handler === b ? this.bindings[a].splice(c, 1) : c++); return e } }, a.prototype.trigger = function () { var a, b, c, d, e, f, g, h, i; if (c = arguments[0], a = 2 <= arguments.length ? X.call(arguments, 1) : [], null != (g = this.bindings) ? g[c] : void 0) { for (e = 0, i = []; e < this.bindings[c].length;) h = this.bindings[c][e], d = h.handler, b = h.ctx, f = h.once, d.apply(null != b ? b : this, a), i.push(f ? this.bindings[c].splice(e, 1) : e++); return i } }, a }(), j = window.Pace || {}, window.Pace = j, v(j, g.prototype), D = j.options = v({}, u, window.paceOptions, x()), U = ["ajax", "document", "eventLag", "elements"], Q = 0, S = U.length; S > Q; Q++) K = U[Q], D[K] === !0 && (D[K] = u[K]); i = function (a) { function b() { return V = b.__super__.constructor.apply(this, arguments) } return Z(b, a), b }(Error), b = function () { function a() { this.progress = 0 } return a.prototype.getElement = function () { var a; if (null == this.el) { if (a = document.querySelector(D.target), !a) throw new i; this.el = document.createElement("div"), this.el.className = "pace pace-active", document.body.className = document.body.className.replace(/pace-done/g, ""), document.body.className += " pace-running", this.el.innerHTML = '
        \n
        \n
        \n
        ', null != a.firstChild ? a.insertBefore(this.el, a.firstChild) : a.appendChild(this.el) } return this.el }, a.prototype.finish = function () { var a; return a = this.getElement(), a.className = a.className.replace("pace-active", ""), a.className += " pace-inactive", document.body.className = document.body.className.replace("pace-running", ""), document.body.className += " pace-done" }, a.prototype.update = function (a) { return this.progress = a, this.render() }, a.prototype.destroy = function () { try { this.getElement().parentNode.removeChild(this.getElement()) } catch (a) { i = a } return this.el = void 0 }, a.prototype.render = function () { var a, b, c, d, e, f, g; if (null == document.querySelector(D.target)) return !1; for (a = this.getElement(), d = "translate3d(" + this.progress + "%, 0, 0)", g = ["webkitTransform", "msTransform", "transform"], e = 0, f = g.length; f > e; e++) b = g[e], a.children[0].style[b] = d; return (!this.lastRenderedProgress || this.lastRenderedProgress | 0 !== this.progress | 0) && (a.children[0].setAttribute("data-progress-text", "" + (0 | this.progress) + "%"), this.progress >= 100 ? c = "99" : (c = this.progress < 10 ? "0" : "", c += 0 | this.progress), a.children[0].setAttribute("data-progress", "" + c)), this.lastRenderedProgress = this.progress }, a.prototype.done = function () { return this.progress >= 100 }, a }(), h = function () { function a() { this.bindings = {} } return a.prototype.trigger = function (a, b) { var c, d, e, f, g; if (null != this.bindings[a]) { for (f = this.bindings[a], g = [], d = 0, e = f.length; e > d; d++) c = f[d], g.push(c.call(this, b)); return g } }, a.prototype.on = function (a, b) { var c; return null == (c = this.bindings)[a] && (c[a] = []), this.bindings[a].push(b) }, a }(), P = window.XMLHttpRequest, O = window.XDomainRequest, N = window.WebSocket, w = function (a, b) { var c, d, e, f; f = []; for (d in b.prototype) try { e = b.prototype[d], f.push(null == a[d] && "function" != typeof e ? a[d] = e : void 0) } catch (g) { c = g } return f }, A = [], j.ignore = function () { var a, b, c; return b = arguments[0], a = 2 <= arguments.length ? X.call(arguments, 1) : [], A.unshift("ignore"), c = b.apply(null, a), A.shift(), c }, j.track = function () { var a, b, c; return b = arguments[0], a = 2 <= arguments.length ? X.call(arguments, 1) : [], A.unshift("track"), c = b.apply(null, a), A.shift(), c }, J = function (a) { var b; if (null == a && (a = "GET"), "track" === A[0]) return "force"; if (!A.length && D.ajax) { if ("socket" === a && D.ajax.trackWebSockets) return !0; if (b = a.toUpperCase(), $.call(D.ajax.trackMethods, b) >= 0) return !0 } return !1 }, k = function (a) { function b() { var a, c = this; b.__super__.constructor.apply(this, arguments), a = function (a) { var b; return b = a.open, a.open = function (d, e) { return J(d) && c.trigger("request", { type: d, url: e, request: a }), b.apply(a, arguments) } }, window.XMLHttpRequest = function (b) { var c; return c = new P(b), a(c), c }; try { w(window.XMLHttpRequest, P) } catch (d) { } if (null != O) { window.XDomainRequest = function () { var b; return b = new O, a(b), b }; try { w(window.XDomainRequest, O) } catch (d) { } } if (null != N && D.ajax.trackWebSockets) { window.WebSocket = function (a, b) { var d; return d = null != b ? new N(a, b) : new N(a), J("socket") && c.trigger("request", { type: "socket", url: a, protocols: b, request: d }), d }; try { w(window.WebSocket, N) } catch (d) { } } } return Z(b, a), b }(h), R = null, y = function () { return null == R && (R = new k), R }, I = function (a) { var b, c, d, e; for (e = D.ajax.ignoreURLs, c = 0, d = e.length; d > c; c++) if (b = e[c], "string" == typeof b) { if (-1 !== a.indexOf(b)) return !0 } else if (b.test(a)) return !0; return !1 }, y().on("request", function (b) { var c, d, e, f, g; return f = b.type, e = b.request, g = b.url, I(g) ? void 0 : j.running || D.restartOnRequestAfter === !1 && "force" !== J(f) ? void 0 : (d = arguments, c = D.restartOnRequestAfter || 0, "boolean" == typeof c && (c = 0), setTimeout(function () { var b, c, g, h, i, k; if (b = "socket" === f ? e.readyState < 2 : 0 < (h = e.readyState) && 4 > h) { for (j.restart(), i = j.sources, k = [], c = 0, g = i.length; g > c; c++) { if (K = i[c], K instanceof a) { K.watch.apply(K, d); break } k.push(void 0) } return k } }, c)) }), a = function () { function a() { var a = this; this.elements = [], y().on("request", function () { return a.watch.apply(a, arguments) }) } return a.prototype.watch = function (a) { var b, c, d, e; return d = a.type, b = a.request, e = a.url, I(e) ? void 0 : (c = "socket" === d ? new n(b) : new o(b), this.elements.push(c)) }, a }(), o = function () { function a(a) { var b, c, d, e, f, g, h = this; if (this.progress = 0, null != window.ProgressEvent) for (c = null, a.addEventListener("progress", function (a) { return h.progress = a.lengthComputable ? 100 * a.loaded / a.total : h.progress + (100 - h.progress) / 2 }, !1), g = ["load", "abort", "timeout", "error"], d = 0, e = g.length; e > d; d++) b = g[d], a.addEventListener(b, function () { return h.progress = 100 }, !1); else f = a.onreadystatechange, a.onreadystatechange = function () { var b; return 0 === (b = a.readyState) || 4 === b ? h.progress = 100 : 3 === a.readyState && (h.progress = 50), "function" == typeof f ? f.apply(null, arguments) : void 0 } } return a }(), n = function () { function a(a) { var b, c, d, e, f = this; for (this.progress = 0, e = ["error", "open"], c = 0, d = e.length; d > c; c++) b = e[c], a.addEventListener(b, function () { return f.progress = 100 }, !1) } return a }(), d = function () { function a(a) { var b, c, d, f; for (null == a && (a = {}), this.elements = [], null == a.selectors && (a.selectors = []), f = a.selectors, c = 0, d = f.length; d > c; c++) b = f[c], this.elements.push(new e(b)) } return a }(), e = function () { function a(a) { this.selector = a, this.progress = 0, this.check() } return a.prototype.check = function () { var a = this; return document.querySelector(this.selector) ? this.done() : setTimeout(function () { return a.check() }, D.elements.checkInterval) }, a.prototype.done = function () { return this.progress = 100 }, a }(), c = function () { function a() { var a, b, c = this; this.progress = null != (b = this.states[document.readyState]) ? b : 100, a = document.onreadystatechange, document.onreadystatechange = function () { return null != c.states[document.readyState] && (c.progress = c.states[document.readyState]), "function" == typeof a ? a.apply(null, arguments) : void 0 } } return a.prototype.states = { loading: 0, interactive: 50, complete: 100 }, a }(), f = function () { function a() { var a, b, c, d, e, f = this; this.progress = 0, a = 0, e = [], d = 0, c = C(), b = setInterval(function () { var g; return g = C() - c - 50, c = C(), e.push(g), e.length > D.eventLag.sampleCount && e.shift(), a = q(e), ++d >= D.eventLag.minSamples && a < D.eventLag.lagThreshold ? (f.progress = 100, clearInterval(b)) : f.progress = 100 * (3 / (a + 3)) }, 50) } return a }(), m = function () { function a(a) { this.source = a, this.last = this.sinceLastUpdate = 0, this.rate = D.initialRate, this.catchup = 0, this.progress = this.lastProgress = 0, null != this.source && (this.progress = F(this.source, "progress")) } return a.prototype.tick = function (a, b) { var c; return null == b && (b = F(this.source, "progress")), b >= 100 && (this.done = !0), b === this.last ? this.sinceLastUpdate += a : (this.sinceLastUpdate && (this.rate = (b - this.last) / this.sinceLastUpdate), this.catchup = (b - this.progress) / D.catchupTime, this.sinceLastUpdate = 0, this.last = b), b > this.progress && (this.progress += this.catchup * a), c = 1 - Math.pow(this.progress / 100, D.easeFactor), this.progress += c * this.rate * a, this.progress = Math.min(this.lastProgress + D.maxProgressPerFrame, this.progress), this.progress = Math.max(0, this.progress), this.progress = Math.min(100, this.progress), this.lastProgress = this.progress, this.progress }, a }(), L = null, H = null, r = null, M = null, p = null, s = null, j.running = !1, z = function () { return D.restartOnPushState ? j.restart() : void 0 }, null != window.history.pushState && (T = window.history.pushState, window.history.pushState = function () { return z(), T.apply(window.history, arguments) }), null != window.history.replaceState && (W = window.history.replaceState, window.history.replaceState = function () { return z(), W.apply(window.history, arguments) }), l = { ajax: a, elements: d, document: c, eventLag: f }, (B = function () { var a, c, d, e, f, g, h, i; for (j.sources = L = [], g = ["ajax", "elements", "document", "eventLag"], c = 0, e = g.length; e > c; c++) a = g[c], D[a] !== !1 && L.push(new l[a](D[a])); for (i = null != (h = D.extraSources) ? h : [], d = 0, f = i.length; f > d; d++) K = i[d], L.push(new K(D)); return j.bar = r = new b, H = [], M = new m })(), j.stop = function () { return j.trigger("stop"), j.running = !1, r.destroy(), s = !0, null != p && ("function" == typeof t && t(p), p = null), B() }, j.restart = function () { return j.trigger("restart"), j.stop(), j.start() }, j.go = function () { var a; return j.running = !0, r.render(), a = C(), s = !1, p = G(function (b, c) { var d, e, f, g, h, i, k, l, n, o, p, q, t, u, v, w; for (l = 100 - r.progress, e = p = 0, f = !0, i = q = 0, u = L.length; u > q; i = ++q) for (K = L[i], o = null != H[i] ? H[i] : H[i] = [], h = null != (w = K.elements) ? w : [K], k = t = 0, v = h.length; v > t; k = ++t) g = h[k], n = null != o[k] ? o[k] : o[k] = new m(g), f &= n.done, n.done || (e++, p += n.tick(b)); return d = p / e, r.update(M.tick(b, d)), r.done() || f || s ? (r.update(100), j.trigger("done"), setTimeout(function () { return r.finish(), j.running = !1, j.trigger("hide") }, Math.max(D.ghostTime, Math.max(D.minTime - (C() - a), 0)))) : c() }) }, j.start = function (a) { v(D, a), j.running = !0; try { r.render() } catch (b) { i = b } return document.querySelector(".pace") ? (j.trigger("start"), j.go()) : setTimeout(j.start, 50) }, "function" == typeof define && define.amd ? define(function () { return j }) : "object" == typeof exports ? module.exports = j : D.startOnPageLoad && j.start() }).call(this); \ No newline at end of file diff --git a/public/plugins/sweetalert2/sweetalert2.min.css b/public/plugins/sweetalert2/sweetalert2.min.css new file mode 100755 index 0000000..6eba97f --- /dev/null +++ b/public/plugins/sweetalert2/sweetalert2.min.css @@ -0,0 +1 @@ +body.swal2-shown{overflow-y:hidden}body.swal2-iosfix{position:fixed;left:0;right:0}.swal2-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;position:fixed;top:0;left:0;bottom:0;right:0;padding:10px;background-color:transparent;z-index:1060}.swal2-container.swal2-fade{-webkit-transition:background-color .1s;transition:background-color .1s}.swal2-container.swal2-shown{background-color:rgba(0,0,0,.4)}.swal2-modal{background-color:#fff;font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;border-radius:5px;box-sizing:border-box;text-align:center;margin:auto;overflow-x:hidden;overflow-y:auto;display:none;position:relative}.swal2-modal:focus{outline:0}.swal2-modal.swal2-loading{overflow-y:hidden}.swal2-modal .swal2-title{color:#595959;font-size:30px;text-align:center;font-weight:600;text-transform:none;position:relative;margin:0 0 .4em;padding:0;display:block}.swal2-modal .swal2-spacer{height:10px;color:transparent;border:0}.swal2-modal .swal2-styled{border:0;border-radius:3px;box-shadow:none;color:#fff;cursor:pointer;font-size:17px;font-weight:500;margin:0 5px;padding:10px 32px}.swal2-modal .swal2-styled:not(.swal2-loading)[disabled]{opacity:.4;cursor:no-drop}.swal2-modal .swal2-styled.swal2-loading{box-sizing:border-box;border:4px solid transparent;border-color:transparent;width:40px;height:40px;padding:0;margin:-2px 30px;vertical-align:top;background-color:transparent!important;color:transparent;cursor:default;border-radius:100%;-webkit-animation:rotate-loading 1.5s linear 0s infinite normal;animation:rotate-loading 1.5s linear 0s infinite normal;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.swal2-modal .swal2-styled+.swal2-styled{margin-top:15px}.swal2-modal :not(.swal2-styled).swal2-loading::after{display:inline-block;content:'';margin-left:5px;vertical-align:-1px;height:6px;width:6px;border:3px solid #999;border-right-color:transparent;border-radius:50%;-webkit-animation:rotate-loading 1.5s linear 0s infinite normal;animation:rotate-loading 1.5s linear 0s infinite normal}.swal2-modal .swal2-image{margin:20px auto;max-width:100%}.swal2-modal .swal2-close{font-size:36px;line-height:36px;font-family:serif;position:absolute;top:5px;right:13px;cursor:pointer;color:#ccc;-webkit-transition:color .1s ease;transition:color .1s ease}.swal2-modal .swal2-close:hover{color:#d55}.swal2-modal>.swal2-checkbox,.swal2-modal>.swal2-file,.swal2-modal>.swal2-input,.swal2-modal>.swal2-radio,.swal2-modal>.swal2-select,.swal2-modal>.swal2-textarea{display:none}.swal2-modal .swal2-content{font-size:18px;text-align:center;font-weight:300;position:relative;float:none;margin:0;padding:0;line-height:normal;color:#545454;word-wrap:break-word}.swal2-modal .swal2-checkbox,.swal2-modal .swal2-file,.swal2-modal .swal2-input,.swal2-modal .swal2-radio,.swal2-modal .swal2-select,.swal2-modal .swal2-textarea{margin:20px auto}.swal2-modal .swal2-file,.swal2-modal .swal2-input,.swal2-modal .swal2-textarea{width:100%;box-sizing:border-box;border-radius:3px;border:1px solid #d9d9d9;font-size:18px;box-shadow:inset 0 1px 1px rgba(0,0,0,.06);-webkit-transition:border-color box-shadow .3s;transition:border-color box-shadow .3s}.swal2-modal .swal2-file.swal2-inputerror,.swal2-modal .swal2-input.swal2-inputerror,.swal2-modal .swal2-textarea.swal2-inputerror{border-color:#f06e57!important}.swal2-modal .swal2-file:focus,.swal2-modal .swal2-input:focus,.swal2-modal .swal2-textarea:focus{outline:0;box-shadow:0 0 3px #c4e6f5;border:1px solid #b4dbed}.swal2-modal .swal2-file:focus::-webkit-input-placeholder,.swal2-modal .swal2-input:focus::-webkit-input-placeholder,.swal2-modal .swal2-textarea:focus::-webkit-input-placeholder{-webkit-transition:opacity .3s .03s ease;transition:opacity .3s .03s ease;opacity:.8}.swal2-modal .swal2-file:focus::-moz-placeholder,.swal2-modal .swal2-input:focus::-moz-placeholder,.swal2-modal .swal2-textarea:focus::-moz-placeholder{-webkit-transition:opacity .3s .03s ease;transition:opacity .3s .03s ease;opacity:.8}.swal2-modal .swal2-file:focus:-ms-input-placeholder,.swal2-modal .swal2-input:focus:-ms-input-placeholder,.swal2-modal .swal2-textarea:focus:-ms-input-placeholder{-webkit-transition:opacity .3s .03s ease;transition:opacity .3s .03s ease;opacity:.8}.swal2-modal .swal2-file:focus::placeholder,.swal2-modal .swal2-input:focus::placeholder,.swal2-modal .swal2-textarea:focus::placeholder{-webkit-transition:opacity .3s .03s ease;transition:opacity .3s .03s ease;opacity:.8}.swal2-modal .swal2-file::-webkit-input-placeholder,.swal2-modal .swal2-input::-webkit-input-placeholder,.swal2-modal .swal2-textarea::-webkit-input-placeholder{color:#e6e6e6}.swal2-modal .swal2-file::-moz-placeholder,.swal2-modal .swal2-input::-moz-placeholder,.swal2-modal .swal2-textarea::-moz-placeholder{color:#e6e6e6}.swal2-modal .swal2-file:-ms-input-placeholder,.swal2-modal .swal2-input:-ms-input-placeholder,.swal2-modal .swal2-textarea:-ms-input-placeholder{color:#e6e6e6}.swal2-modal .swal2-file::placeholder,.swal2-modal .swal2-input::placeholder,.swal2-modal .swal2-textarea::placeholder{color:#e6e6e6}.swal2-modal .swal2-range input{float:left;width:80%}.swal2-modal .swal2-range output{float:right;width:20%;font-size:20px;font-weight:600;text-align:center}.swal2-modal .swal2-range input,.swal2-modal .swal2-range output{height:43px;line-height:43px;vertical-align:middle;margin:20px auto;padding:0}.swal2-modal .swal2-input{height:43px;padding:0 12px}.swal2-modal .swal2-input[type=number]{max-width:150px}.swal2-modal .swal2-file{font-size:20px}.swal2-modal .swal2-textarea{height:108px;padding:12px}.swal2-modal .swal2-select{color:#545454;font-size:inherit;padding:5px 10px;min-width:40%;max-width:100%}.swal2-modal .swal2-radio{border:0}.swal2-modal .swal2-radio label:not(:first-child){margin-left:20px}.swal2-modal .swal2-radio input,.swal2-modal .swal2-radio span{vertical-align:middle}.swal2-modal .swal2-radio input{margin:0 3px 0 0}.swal2-modal .swal2-checkbox{color:#545454}.swal2-modal .swal2-checkbox input,.swal2-modal .swal2-checkbox span{vertical-align:middle}.swal2-modal .swal2-validationerror{background-color:#f0f0f0;margin:0 -20px;overflow:hidden;padding:10px;color:gray;font-size:16px;font-weight:300;display:none}.swal2-modal .swal2-validationerror::before{content:'!';display:inline-block;width:24px;height:24px;border-radius:50%;background-color:#ea7d7d;color:#fff;line-height:24px;text-align:center;margin-right:10px}@supports (-ms-accelerator:true){.swal2-range input{width:100%!important}.swal2-range output{display:none}}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.swal2-range input{width:100%!important}.swal2-range output{display:none}}.swal2-icon{width:80px;height:80px;border:4px solid transparent;border-radius:50%;margin:20px auto 30px;padding:0;position:relative;box-sizing:content-box;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.swal2-icon.swal2-error{border-color:#f27474}.swal2-icon.swal2-error .x-mark{position:relative;display:block}.swal2-icon.swal2-error .line{position:absolute;height:5px;width:47px;background-color:#f27474;display:block;top:37px;border-radius:2px}.swal2-icon.swal2-error .line.left{-webkit-transform:rotate(45deg);transform:rotate(45deg);left:17px}.swal2-icon.swal2-error .line.right{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);right:16px}.swal2-icon.swal2-warning{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;color:#f8bb86;border-color:#facea8;font-size:60px;line-height:80px;text-align:center}.swal2-icon.swal2-info{font-family:'Open Sans',sans-serif;color:#3fc3ee;border-color:#9de0f6;font-size:60px;line-height:80px;text-align:center}.swal2-icon.swal2-question{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;color:#87adbd;border-color:#c9dae1;font-size:60px;line-height:80px;text-align:center}.swal2-icon.swal2-success{border-color:#a5dc86}.swal2-icon.swal2-success::after,.swal2-icon.swal2-success::before{content:'';border-radius:50%;position:absolute;width:60px;height:120px;background:#fff;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.swal2-icon.swal2-success::before{border-radius:120px 0 0 120px;top:-7px;left:-33px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:60px 60px;transform-origin:60px 60px}.swal2-icon.swal2-success::after{border-radius:0 120px 120px 0;top:-11px;left:30px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:0 60px;transform-origin:0 60px}.swal2-icon.swal2-success .placeholder{width:80px;height:80px;border:4px solid rgba(165,220,134,.2);border-radius:50%;box-sizing:content-box;position:absolute;left:-4px;top:-4px;z-index:2}.swal2-icon.swal2-success .fix{width:7px;height:90px;background-color:#fff;position:absolute;left:28px;top:8px;z-index:1;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.swal2-icon.swal2-success .line{height:5px;background-color:#a5dc86;display:block;border-radius:2px;position:absolute;z-index:2}.swal2-icon.swal2-success .line.tip{width:25px;left:14px;top:46px;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.swal2-icon.swal2-success .line.long{width:47px;right:8px;top:38px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.swal2-progresssteps{font-weight:600;margin:0 0 20px;padding:0}.swal2-progresssteps li{display:inline-block;position:relative}.swal2-progresssteps .swal2-progresscircle{background:#3085d6;border-radius:2em;color:#fff;height:2em;line-height:2em;text-align:center;width:2em;z-index:20}.swal2-progresssteps .swal2-progresscircle:first-child{margin-left:0}.swal2-progresssteps .swal2-progresscircle:last-child{margin-right:0}.swal2-progresssteps .swal2-progresscircle.swal2-activeprogressstep{background:#3085d6}.swal2-progresssteps .swal2-progresscircle.swal2-activeprogressstep~.swal2-progresscircle{background:#add8e6}.swal2-progresssteps .swal2-progresscircle.swal2-activeprogressstep~.swal2-progressline{background:#add8e6}.swal2-progresssteps .swal2-progressline{background:#3085d6;height:.4em;margin:0 -1px;z-index:10}[class^=swal2]{-webkit-tap-highlight-color:transparent}@-webkit-keyframes showSweetAlert{0%{-webkit-transform:scale(.7);transform:scale(.7)}45%{-webkit-transform:scale(1.05);transform:scale(1.05)}80%{-webkit-transform:scale(.95);transform:scale(.95)}100%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes showSweetAlert{0%{-webkit-transform:scale(.7);transform:scale(.7)}45%{-webkit-transform:scale(1.05);transform:scale(1.05)}80%{-webkit-transform:scale(.95);transform:scale(.95)}100%{-webkit-transform:scale(1);transform:scale(1)}}@-webkit-keyframes hideSweetAlert{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}100%{-webkit-transform:scale(.5);transform:scale(.5);opacity:0}}@keyframes hideSweetAlert{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}100%{-webkit-transform:scale(.5);transform:scale(.5);opacity:0}}.swal2-show{-webkit-animation:showSweetAlert .3s;animation:showSweetAlert .3s}.swal2-show.swal2-noanimation{-webkit-animation:none;animation:none}.swal2-hide{-webkit-animation:hideSweetAlert .15s forwards;animation:hideSweetAlert .15s forwards}.swal2-hide.swal2-noanimation{-webkit-animation:none;animation:none}@-webkit-keyframes animate-success-tip{0%{width:0;left:1px;top:19px}54%{width:0;left:1px;top:19px}70%{width:50px;left:-8px;top:37px}84%{width:17px;left:21px;top:48px}100%{width:25px;left:14px;top:45px}}@keyframes animate-success-tip{0%{width:0;left:1px;top:19px}54%{width:0;left:1px;top:19px}70%{width:50px;left:-8px;top:37px}84%{width:17px;left:21px;top:48px}100%{width:25px;left:14px;top:45px}}@-webkit-keyframes animate-success-long{0%{width:0;right:46px;top:54px}65%{width:0;right:46px;top:54px}84%{width:55px;right:0;top:35px}100%{width:47px;right:8px;top:38px}}@keyframes animate-success-long{0%{width:0;right:46px;top:54px}65%{width:0;right:46px;top:54px}84%{width:55px;right:0;top:35px}100%{width:47px;right:8px;top:38px}}@-webkit-keyframes rotatePlaceholder{0%{-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}5%{-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}12%{-webkit-transform:rotate(-405deg);transform:rotate(-405deg)}100%{-webkit-transform:rotate(-405deg);transform:rotate(-405deg)}}@keyframes rotatePlaceholder{0%{-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}5%{-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}12%{-webkit-transform:rotate(-405deg);transform:rotate(-405deg)}100%{-webkit-transform:rotate(-405deg);transform:rotate(-405deg)}}.animate-success-tip{-webkit-animation:animate-success-tip .75s;animation:animate-success-tip .75s}.animate-success-long{-webkit-animation:animate-success-long .75s;animation:animate-success-long .75s}.swal2-success.animate::after{-webkit-animation:rotatePlaceholder 4.25s ease-in;animation:rotatePlaceholder 4.25s ease-in}@-webkit-keyframes animate-error-icon{0%{-webkit-transform:rotateX(100deg);transform:rotateX(100deg);opacity:0}100%{-webkit-transform:rotateX(0);transform:rotateX(0);opacity:1}}@keyframes animate-error-icon{0%{-webkit-transform:rotateX(100deg);transform:rotateX(100deg);opacity:0}100%{-webkit-transform:rotateX(0);transform:rotateX(0);opacity:1}}.animate-error-icon{-webkit-animation:animate-error-icon .5s;animation:animate-error-icon .5s}@-webkit-keyframes animate-x-mark{0%{-webkit-transform:scale(.4);transform:scale(.4);margin-top:26px;opacity:0}50%{-webkit-transform:scale(.4);transform:scale(.4);margin-top:26px;opacity:0}80%{-webkit-transform:scale(1.15);transform:scale(1.15);margin-top:-6px}100%{-webkit-transform:scale(1);transform:scale(1);margin-top:0;opacity:1}}@keyframes animate-x-mark{0%{-webkit-transform:scale(.4);transform:scale(.4);margin-top:26px;opacity:0}50%{-webkit-transform:scale(.4);transform:scale(.4);margin-top:26px;opacity:0}80%{-webkit-transform:scale(1.15);transform:scale(1.15);margin-top:-6px}100%{-webkit-transform:scale(1);transform:scale(1);margin-top:0;opacity:1}}.animate-x-mark{-webkit-animation:animate-x-mark .5s;animation:animate-x-mark .5s}@-webkit-keyframes pulse-warning{0%{border-color:#f8d486}100%{border-color:#f8bb86}}@keyframes pulse-warning{0%{border-color:#f8d486}100%{border-color:#f8bb86}}.pulse-warning{-webkit-animation:pulse-warning .75s infinite alternate;animation:pulse-warning .75s infinite alternate}@-webkit-keyframes rotate-loading{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes rotate-loading{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}} \ No newline at end of file diff --git a/public/plugins/sweetalert2/sweetalert2.min.js b/public/plugins/sweetalert2/sweetalert2.min.js new file mode 100755 index 0000000..249bf76 --- /dev/null +++ b/public/plugins/sweetalert2/sweetalert2.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Sweetalert2=t()}(this,function(){"use strict";var e={title:"",titleText:"",text:"",html:"",type:null,customClass:"",target:"body",animation:!0,allowOutsideClick:!0,allowEscapeKey:!0,allowEnterKey:!0,showConfirmButton:!0,showCancelButton:!1,preConfirm:null,confirmButtonText:"OK",confirmButtonColor:"#3085d6",confirmButtonClass:null,cancelButtonText:"Cancel",cancelButtonColor:"#aaa",cancelButtonClass:null,buttonsStyling:!0,reverseButtons:!1,focusCancel:!1,showCloseButton:!1,showLoaderOnConfirm:!1,imageUrl:null,imageWidth:null,imageHeight:null,imageClass:null,timer:null,width:500,padding:20,background:"#fff",input:null,inputPlaceholder:"",inputValue:"",inputOptions:{},inputAutoTrim:!0,inputClass:null,inputAttributes:{},inputValidator:null,progressSteps:[],currentProgressStep:null,progressStepsDistance:"40px",onOpen:null,onClose:null},t=function(e){var t={};for(var n in e)t[e[n]]="swal2-"+e[n];return t},n=t(["container","shown","iosfix","modal","overlay","fade","show","hide","noanimation","close","title","content","spacer","confirm","cancel","icon","image","input","file","range","select","radio","checkbox","textarea","inputerror","validationerror","progresssteps","activeprogressstep","progresscircle","progressline","loading","styled"]),o=t(["success","warning","info","question","error"]),r=function(e,t){e=String(e).replace(/[^0-9a-f]/gi,""),e.length<6&&(e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]),t=t||0;for(var n="#",o=0;o<3;o++){var r=parseInt(e.substr(2*o,2),16);r=Math.round(Math.min(Math.max(0,r+r*t),255)).toString(16),n+=("00"+r).substr(r.length)}return n},i={previousWindowKeyDown:null,previousActiveElement:null,previousBodyPadding:null},a=function(e){if("undefined"==typeof document)return void console.error("SweetAlert2 requires document to initialize");var t=document.createElement("div");t.className=n.container,t.innerHTML=l;var o=document.querySelector(e.target);o||(console.warn("SweetAlert2: Can't find the target \""+e.target+'"'),o=document.body),o.appendChild(t);var r=u(),i=B(r,n.input),a=B(r,n.file),s=r.querySelector("."+n.range+" input"),c=r.querySelector("."+n.range+" output"),d=B(r,n.select),p=r.querySelector("."+n.checkbox+" input"),f=B(r,n.textarea);return i.oninput=function(){$.resetValidationError()},i.onkeydown=function(t){setTimeout(function(){13===t.keyCode&&e.allowEnterKey&&(t.stopPropagation(),$.clickConfirm())},0)},a.onchange=function(){$.resetValidationError()},s.oninput=function(){$.resetValidationError(),c.value=s.value},s.onchange=function(){$.resetValidationError(),s.previousSibling.value=s.value},d.onchange=function(){$.resetValidationError()},p.onchange=function(){$.resetValidationError()},f.oninput=function(){$.resetValidationError()},r},l=('\n \n').replace(/(^|\n)\s*/g,""),s=function(){return document.body.querySelector("."+n.container)},u=function(){return s()?s().querySelector("."+n.modal):null},c=function(){return u().querySelectorAll("."+n.icon)},d=function(e){return s()?s().querySelector("."+e):null},p=function(){return d(n.title)},f=function(){return d(n.content)},m=function(){return d(n.image)},v=function(){return d(n.spacer)},h=function(){return d(n.progresssteps)},y=function(){return d(n.validationerror)},g=function(){return d(n.confirm)},b=function(){return d(n.cancel)},w=function(){return d(n.close)},C=function(e){var t=[g(),b()];return e&&t.reverse(),t.concat(Array.prototype.slice.call(u().querySelectorAll("button:not([class^=swal2-]), input:not([type=hidden]), textarea, select")))},k=function(e,t){return!!e.classList&&e.classList.contains(t)},x=function(e){if(e.focus(),"file"!==e.type){var t=e.value;e.value="",e.value=t}},S=function(e,t){if(e&&t){t.split(/\s+/).filter(Boolean).forEach(function(t){e.classList.add(t)})}},E=function(e,t){if(e&&t){t.split(/\s+/).filter(Boolean).forEach(function(t){e.classList.remove(t)})}},B=function(e,t){for(var n=0;n"),t.text||t.html){if("object"===N(t.html))if(s.innerHTML="",0 in t.html)for(var k=0;k in t.html;k++)s.appendChild(t.html[k].cloneNode(!0));else s.appendChild(t.html.cloneNode(!0));else t.html?s.innerHTML=t.html:t.text&&(s.textContent=t.text);A(s)}else P(s);t.showCloseButton?A(C):P(C),r.className=n.modal,t.customClass&&S(r,t.customClass);var x=h(),B=parseInt(null===t.currentProgressStep?$.getQueueStep():t.currentProgressStep,10);t.progressSteps.length?(A(x),T(x),B>=t.progressSteps.length&&console.warn("SweetAlert2: Invalid currentProgressStep parameter, it should be less than progressSteps.length (currentProgressStep like JS arrays starts from 0)"),t.progressSteps.forEach(function(e,o){var r=document.createElement("li");if(S(r,n.progresscircle),r.innerHTML=e,o===B&&S(r,n.activeprogressstep),x.appendChild(r),o!==t.progressSteps.length-1){var i=document.createElement("li");S(i,n.progressline),i.style.width=t.progressStepsDistance,x.appendChild(i)}})):P(x);for(var L=c(),q=0;qwindow.innerHeight&&(i.previousBodyPadding=document.body.style.paddingRight,document.body.style.paddingRight=H()+"px")},Q=function(){null!==i.previousBodyPadding&&(document.body.style.paddingRight=i.previousBodyPadding,i.previousBodyPadding=null)},Y=function(){if(/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream&&!k(document.body,n.iosfix)){var e=document.body.scrollTop;document.body.style.top=e*-1+"px",S(document.body,n.iosfix)}},Z=function(){if(k(document.body,n.iosfix)){var e=parseInt(document.body.style.top,10);E(document.body,n.iosfix),document.body.style.top="",document.body.scrollTop=e*-1}},$=function e(){for(var t=arguments.length,o=Array(t),a=0;a -
        - - - - - - - - - - - - - {{range .Keys}} - - - - - - - - - - {{end}} - -
        名称 Key创建者是否是Session创建时间 过期时间 操作
        -

        - - {{.Name}} -

        -
        {{.Token}}{{.CreatedBy}}{{.IsSession}}{{TimeSince .CreatedAt}}{{TimeSince .ExpiresAt}} - -
        +
        +
        + + + + + + + + + + + + + + {{range .Keys}} + + + + + + + + + + {{end}} + +
        Name KeyCreaterIs SessionCreate Time Expire Time Operation
        +

        + {{.Name}} +

        +
        {{.Token}}{{.CreatedBy}}{{.IsSession}}{{TimeSince .CreatedAt}}{{TimeSince .ExpiresAt}} + +
        +
        +
        +
        +
        + + -{{template "base/footer" .}} \ No newline at end of file +{{template "base/footer" .}} + + + \ No newline at end of file diff --git a/template/app/detail/collaborators.html b/template/app/detail/collaborators.html new file mode 100644 index 0000000..cef9e68 --- /dev/null +++ b/template/app/detail/collaborators.html @@ -0,0 +1,271 @@ +{{template "base/header" .}} +
        + +{{template "app/detail/header" .}} + +
        + + {{$user := .SignedUser}} + {{$owner := .Owner}} + {{$condition1 := ne $user.Email $owner}} +
        +
        +
        + Collaborators + +
        +
        +
        + {{range .Collaborators}} +
        +
        + label-image +
        +
        + {{.Email}} +
        + {{if eq .Role 1}}Owner{{else}}Member{{end}} +
        +
        +

        +
        +
        + + {{$condition2 := eq $user.Email .Email}} + + +
        +
        +
        + {{end}} +
        +
        +
        +
        +
        +
        +{{template "base/footer" .}} + + + diff --git a/template/app/detail/deployments.html b/template/app/detail/deployments.html new file mode 100644 index 0000000..c6c43a1 --- /dev/null +++ b/template/app/detail/deployments.html @@ -0,0 +1,221 @@ +{{template "base/header" .}} +
        + + {{template "app/detail/header" .}} +
        + {{$user := .SignedUser}} {{$owner := .Owner}} {{$condition := ne $user.Email $owner}} +
        +
        +
        + Summary + +
        +
        +
        + {{range .Deployments}} +
        +
        + {{.Name}} +
        + {{.Key}} +
        + + {{$pkg := .Package}} {{$metrics := .PackageMetrics}} +
        + {{if $pkg}} + + + + + + + + + + + + + +
        Update Metadata Install Metrics
        +
        +
        + +
        + Label:  {{$pkg.Label}} +
        +
        +
        + +
        + App Version:  {{$pkg.AppVersion}} +
        +
        +
        + +
        + Mandatory:  {{$pkg.IsMandatory}} +
        +
        +
        + +
        + Release Time:   {{$time := Time $pkg.UploadTime}} {{DateFmtShort $time}} +
        +
        +
        + +
        + Released By:  {{$pkg.ReleasedBy}} +
        +
        +
        +
        +
        +
        + +
        + Active:  {{if $metrics}}{{Persent $metrics.Active $metrics.TotalActive}}%({{$metrics.Active}} of {{$metrics.TotalActive}}){{end}} +
        +
        +
        + +
        + Total:  {{if $metrics}}{{$metrics.Installed}}{{end}} +
        +
        +
        + +
        + Rollbacks:  {{if $metrics}}{{$metrics.Failed}}{{end}} +
        +
        +
        +
        + {{else}} No Packge Released {{end}} +
        +
        + + + + +
        +
        +
        + {{end}} +
        +
        +
        +
        +
        +
        +
        + History + +
        +
        +
        + + + + + + + + + + + + + +
        LabelApp VersionMandatoryRelease MethodRelease TimeDescription Install Metrics
        +
        +
        +
        +
        + + + +
        +{{template "base/footer" .}} + + + + \ No newline at end of file diff --git a/template/app/detail/header.html b/template/app/detail/header.html new file mode 100644 index 0000000..f7c5bcf --- /dev/null +++ b/template/app/detail/header.html @@ -0,0 +1,23 @@ +
        +
        +
        +
        + + label-image + +
        +
        + {{.AppName}} +
        +
        + Owner {{.Owner}} +
        +
        +
        +
        +
        +
        + \ No newline at end of file diff --git a/template/app/list.html b/template/app/list.html index aee8108..7d844d5 100644 --- a/template/app/list.html +++ b/template/app/list.html @@ -1,61 +1,89 @@ {{template "base/header" .}} -
        - - - - - - - - - - - {{range .Apps}} - - - - - - - {{end}} - -
        名称 成员部署 操作
        {{.Name}} + -
        - {{range .Deployments}}
        -
        {{.}}
        +
        + {{len .Deployments}} Deployments +
        - {{end}}
        -
        - - - -
        +
        + + + + {{end}} + +
        +
        + +
        +
        + + + -{{template "base/footer" .}} \ No newline at end of file + +{{template "base/footer" .}} + \ No newline at end of file diff --git a/template/auth/activate.html b/template/auth/activate.html index f4da94e..d85b361 100755 --- a/template/auth/activate.html +++ b/template/auth/activate.html @@ -1,38 +1,36 @@ -{{template "base/header" .}} -
        -
        -
        -
        - {{.CsrfTokenHtml}} -

        - 激活您的帐户 -

        -
        - {{template "base/alert" .}} - {{if .IsActivatePage}} - {{if .ServiceNotEnabled}} -

        对不起,注册邮箱确认功能已被关闭}

        +{{template "base/header_2" .}} +
        +
        +
        +
        + + {{.CsrfTokenHtml}} +

        + 激活您的帐户 +

        +
        + {{template "base/alert" .}} {{if .IsActivatePage}} {{if .ServiceNotEnabled}} +

        对不起,注册邮箱确认功能已被关闭}

        {{else if .ResendLimited}} -

        对不起,您请求发送激活邮件过于频繁,请等待 3 分钟后再试

        +

        对不起,您请求发送激活邮件过于频繁,请等待 3 分钟后再试

        {{else}} -

        一封新的确认邮件已经被发送至 {{.Email}},请检查您的收件箱并在 {{.Hours}} 小时内完成确认注册操作。

        - {{end}} - {{else}} - {{if .IsSendRegisterMail}} -

        一封确认邮件已经被发送至 {{.Email}},请检查您的收件箱并在 {{.Hours}} 小时内完成确认注册操作。

        +

        一封新的确认邮件已经被发送至 {{.Email}},请检查您的收件箱并在 {{.Hours}} 小时内完成确认注册操作。

        + {{end}} {{else}} {{if .IsSendRegisterMail}} +

        一封确认邮件已经被发送至 {{.Email}},请检查您的收件箱并在 {{.Hours}} 小时内完成确认注册操作。

        {{else if .IsActivateFailed}} -

        对不起,您的确认代码已过期或已失效。

        +

        对不起,您的确认代码已过期或已失效。

        {{else}} -

        {{.SignedUser.UserName}} 您好,系统检测到您有一封发送至 {{.SignedUser.Email}} 但未被确认的邮件。如果您未收到激活邮件,或需要重新发送,请单击下方的按钮。

        -
        -
        - -
        - {{end}} - {{end}} -
        - +

        {{.SignedUser.UserName}} 您好,系统检测到您有一封发送至 {{.SignedUser.Email}} 但未被确认的邮件。如果您未收到激活邮件,或需要重新发送,请单击下方的按钮。

        +
        +
        + +
        + {{end}} {{end}} +
        + +
        -{{template "base/footer" .}} +{{template "base/footer_2" .}} +{{template "base/background" .}} \ No newline at end of file diff --git a/template/auth/forgot_passwd.html b/template/auth/forgot_passwd.html index 3e4ec5a..385a539 100755 --- a/template/auth/forgot_passwd.html +++ b/template/auth/forgot_passwd.html @@ -1,7 +1,8 @@ -{{template "base/header" .}} -
        -
        -
        +{{template "base/header_2" .}} +
        +
        +
        +
        {{.CsrfTokenHtml}}

        @@ -29,6 +30,8 @@

        +
        -{{template "base/footer" .}} +{{template "base/footer_2" .}} +{{template "base/background" .}} diff --git a/template/auth/prohibit_login.html b/template/auth/prohibit_login.html index 18d6f04..d64d7cf 100755 --- a/template/auth/prohibit_login.html +++ b/template/auth/prohibit_login.html @@ -1,16 +1,19 @@ -{{template "base/header" .}} -
        -
        -
        -
        -

        - 该帐户被禁止登录 -

        -
        -

        您的帐户被禁止登录,请联系网站管理员

        -
        -
        +{{template "base/header_2" .}} +
        +
        +
        +
        +
        +

        + 该帐户被禁止登录 +

        +
        +

        您的帐户被禁止登录,请联系网站管理员

        +
        +
        +
        -{{template "base/footer" .}} +{{template "base/footer_2" .}} +{{template "base/background" .}} \ No newline at end of file diff --git a/template/auth/reset_passwd.html b/template/auth/reset_passwd.html index bff7dfe..c17eb22 100755 --- a/template/auth/reset_passwd.html +++ b/template/auth/reset_passwd.html @@ -1,7 +1,8 @@ -{{template "base/header" .}} -
        -
        -
        +{{template "base/header_2" .}} +
        +
        +
        +
        {{.CsrfTokenHtml}} @@ -26,6 +27,8 @@

        +
        -{{template "base/footer" .}} +{{template "base/footer_2" .}} +{{template "base/background" .}} diff --git a/template/auth/signin.html b/template/auth/signin.html index 825eb08..660a553 100755 --- a/template/auth/signin.html +++ b/template/auth/signin.html @@ -1,5 +1,4 @@ -{{template "base/header" .}} -