Bläddra i källkod

Refactoring: rename pkg/base -> pkg/tool

Unknwon 8 år sedan
förälder
incheckning
6fbb984ebf
51 ändrade filer med 254 tillägg och 255 borttagningar
  1. 5 5
      models/action.go
  2. 2 2
      models/admin.go
  3. 2 2
      models/git_diff.go
  4. 2 2
      models/issue.go
  5. 3 3
      models/issue_label.go
  6. 3 3
      models/migrations/migrations.go
  7. 7 7
      models/repo_branch.go
  8. 2 2
      models/ssh_key.go
  9. 2 2
      models/token.go
  10. 16 16
      models/user.go
  11. 2 2
      pkg/auth/auth.go
  12. 2 2
      pkg/context/api.go
  13. 5 5
      pkg/context/context.go
  14. 10 10
      pkg/mailer/mail.go
  15. 2 2
      pkg/markup/markdown.go
  16. 2 2
      pkg/markup/markup.go
  17. 15 15
      pkg/template/template.go
  18. 1 1
      pkg/tool/base.go
  19. 1 1
      pkg/tool/file.go
  20. 1 1
      pkg/tool/tool.go
  21. 24 24
      routers/admin/admin.go
  22. 4 4
      routers/admin/auths.go
  23. 2 2
      routers/admin/notice.go
  24. 2 2
      routers/admin/orgs.go
  25. 2 2
      routers/admin/repos.go
  26. 4 4
      routers/admin/users.go
  27. 2 2
      routers/dev/template.go
  28. 6 6
      routers/home.go
  29. 3 3
      routers/install.go
  30. 3 3
      routers/org/members.go
  31. 2 2
      routers/org/org.go
  32. 4 4
      routers/org/setting.go
  33. 5 5
      routers/org/teams.go
  34. 3 3
      routers/repo/branch.go
  35. 5 5
      routers/repo/commit.go
  36. 3 3
      routers/repo/download.go
  37. 6 6
      routers/repo/editor.go
  38. 3 3
      routers/repo/http.go
  39. 10 10
      routers/repo/issue.go
  40. 6 6
      routers/repo/pull.go
  41. 3 3
      routers/repo/release.go
  42. 5 5
      routers/repo/repo.go
  43. 8 8
      routers/repo/setting.go
  44. 11 11
      routers/repo/view.go
  45. 5 5
      routers/repo/webhook.go
  46. 5 5
      routers/repo/wiki.go
  47. 6 6
      routers/user/auth.go
  48. 6 6
      routers/user/home.go
  49. 3 3
      routers/user/profile.go
  50. 14 15
      routers/user/setting.go
  51. 4 4
      templates/user/settings/navbar.tmpl

+ 5 - 5
models/action.go

@@ -21,7 +21,7 @@ import (
 	api "github.com/gogits/go-gogs-client"
 
 	"github.com/gogits/gogs/models/errors"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/setting"
 )
 
@@ -108,7 +108,7 @@ func (a *Action) GetActUserName() string {
 }
 
 func (a *Action) ShortActUserName() string {
-	return base.EllipsisString(a.ActUserName, 20)
+	return tool.EllipsisString(a.ActUserName, 20)
 }
 
 func (a *Action) GetRepoUserName() string {
@@ -116,7 +116,7 @@ func (a *Action) GetRepoUserName() string {
 }
 
 func (a *Action) ShortRepoUserName() string {
-	return base.EllipsisString(a.RepoUserName, 20)
+	return tool.EllipsisString(a.RepoUserName, 20)
 }
 
 func (a *Action) GetRepoName() string {
@@ -124,7 +124,7 @@ func (a *Action) GetRepoName() string {
 }
 
 func (a *Action) ShortRepoName() string {
-	return base.EllipsisString(a.RepoName, 33)
+	return tool.EllipsisString(a.RepoName, 33)
 }
 
 func (a *Action) GetRepoPath() string {
@@ -305,7 +305,7 @@ func (push *PushCommits) AvatarLink(email string) string {
 	if !ok {
 		u, err := GetUserByEmail(email)
 		if err != nil {
-			push.avatars[email] = base.AvatarLink(email)
+			push.avatars[email] = tool.AvatarLink(email)
 			if !errors.IsUserNotExist(err) {
 				log.Error(4, "GetUserByEmail: %v", err)
 			}

+ 2 - 2
models/admin.go

@@ -15,7 +15,7 @@ import (
 	"github.com/go-xorm/xorm"
 	log "gopkg.in/clog.v1"
 
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/setting"
 )
 
@@ -128,6 +128,6 @@ func DeleteNoticesByIDs(ids []int64) error {
 	if len(ids) == 0 {
 		return nil
 	}
-	_, err := x.Where("id IN (" + strings.Join(base.Int64sToStrings(ids), ",") + ")").Delete(new(Notice))
+	_, err := x.Where("id IN (" + strings.Join(tool.Int64sToStrings(ids), ",") + ")").Delete(new(Notice))
 	return err
 }

+ 2 - 2
models/git_diff.go

@@ -17,7 +17,7 @@ import (
 
 	"github.com/gogits/git-module"
 
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/setting"
 	"github.com/gogits/gogs/pkg/template/highlight"
 )
@@ -145,7 +145,7 @@ func NewDiff(gitDiff *git.Diff) *Diff {
 			}
 		}
 
-		charsetLabel, err := base.DetectEncoding(buf.Bytes())
+		charsetLabel, err := tool.DetectEncoding(buf.Bytes())
 		if charsetLabel != "UTF-8" && err == nil {
 			encoding, _ := charset.Lookup(charsetLabel)
 			if encoding != nil {

+ 2 - 2
models/issue.go

@@ -16,7 +16,7 @@ import (
 	api "github.com/gogits/go-gogs-client"
 
 	"github.com/gogits/gogs/models/errors"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/setting"
 )
 
@@ -1213,7 +1213,7 @@ func GetIssueStats(opts *IssueStatsOptions) *IssueStats {
 		sess := x.Where("issue.repo_id = ?", opts.RepoID).And("is_pull = ?", opts.IsPull)
 
 		if len(opts.Labels) > 0 && opts.Labels != "0" {
-			labelIDs := base.StringsToInt64s(strings.Split(opts.Labels, ","))
+			labelIDs := tool.StringsToInt64s(strings.Split(opts.Labels, ","))
 			if len(labelIDs) > 0 {
 				sess.Join("INNER", "issue_label", "issue.id = issue_id").In("label_id", labelIDs)
 			}

+ 3 - 3
models/issue_label.go

@@ -15,7 +15,7 @@ import (
 
 	api "github.com/gogits/go-gogs-client"
 
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 )
 
 var labelColorPattern = regexp.MustCompile("#([a-fA-F0-9]{6})")
@@ -138,7 +138,7 @@ func GetLabelOfRepoByID(repoID, labelID int64) (*Label, error) {
 // it silently ignores label IDs that are not belong to the repository.
 func GetLabelsInRepoByIDs(repoID int64, labelIDs []int64) ([]*Label, error) {
 	labels := make([]*Label, 0, len(labelIDs))
-	return labels, x.Where("repo_id = ?", repoID).In("id", base.Int64sToStrings(labelIDs)).Asc("name").Find(&labels)
+	return labels, x.Where("repo_id = ?", repoID).In("id", tool.Int64sToStrings(labelIDs)).Asc("name").Find(&labels)
 }
 
 // GetLabelsByRepoID returns all labels that belong to given repository by ID.
@@ -161,7 +161,7 @@ func getLabelsByIssueID(e Engine, issueID int64) ([]*Label, error) {
 	}
 
 	labels := make([]*Label, 0, len(labelIDs))
-	return labels, e.Where("id > 0").In("id", base.Int64sToStrings(labelIDs)).Asc("name").Find(&labels)
+	return labels, e.Where("id > 0").In("id", tool.Int64sToStrings(labelIDs)).Asc("name").Find(&labels)
 }
 
 // GetLabelsByIssueID returns all labels that belong to given issue by ID.

+ 3 - 3
models/migrations/migrations.go

@@ -13,7 +13,7 @@ import (
 	"github.com/go-xorm/xorm"
 	log "gopkg.in/clog.v1"
 
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 )
 
 const _MIN_DB_VER = 10
@@ -159,10 +159,10 @@ func generateOrgRandsAndSalt(x *xorm.Engine) (err error) {
 	}
 
 	for _, org := range orgs {
-		if org.Rands, err = base.GetRandomString(10); err != nil {
+		if org.Rands, err = tool.GetRandomString(10); err != nil {
 			return err
 		}
-		if org.Salt, err = base.GetRandomString(10); err != nil {
+		if org.Salt, err = tool.GetRandomString(10); err != nil {
 			return err
 		}
 		if _, err = sess.Id(org.ID).Update(org); err != nil {

+ 7 - 7
models/repo_branch.go

@@ -11,7 +11,7 @@ import (
 	"github.com/Unknwon/com"
 	"github.com/gogits/git-module"
 
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 )
 
 type Branch struct {
@@ -149,10 +149,10 @@ func UpdateOrgProtectBranch(repo *Repository, protectBranch *ProtectBranch, whit
 	}
 
 	hasUsersChanged := false
-	validUserIDs := base.StringsToInt64s(strings.Split(protectBranch.WhitelistUserIDs, ","))
+	validUserIDs := tool.StringsToInt64s(strings.Split(protectBranch.WhitelistUserIDs, ","))
 	if protectBranch.WhitelistUserIDs != whitelistUserIDs {
 		hasUsersChanged = true
-		userIDs := base.StringsToInt64s(strings.Split(whitelistUserIDs, ","))
+		userIDs := tool.StringsToInt64s(strings.Split(whitelistUserIDs, ","))
 		validUserIDs = make([]int64, 0, len(userIDs))
 		for _, userID := range userIDs {
 			has, err := HasAccess(userID, repo, ACCESS_MODE_WRITE)
@@ -165,14 +165,14 @@ func UpdateOrgProtectBranch(repo *Repository, protectBranch *ProtectBranch, whit
 			validUserIDs = append(validUserIDs, userID)
 		}
 
-		protectBranch.WhitelistUserIDs = strings.Join(base.Int64sToStrings(validUserIDs), ",")
+		protectBranch.WhitelistUserIDs = strings.Join(tool.Int64sToStrings(validUserIDs), ",")
 	}
 
 	hasTeamsChanged := false
-	validTeamIDs := base.StringsToInt64s(strings.Split(protectBranch.WhitelistTeamIDs, ","))
+	validTeamIDs := tool.StringsToInt64s(strings.Split(protectBranch.WhitelistTeamIDs, ","))
 	if protectBranch.WhitelistTeamIDs != whitelistTeamIDs {
 		hasTeamsChanged = true
-		teamIDs := base.StringsToInt64s(strings.Split(whitelistTeamIDs, ","))
+		teamIDs := tool.StringsToInt64s(strings.Split(whitelistTeamIDs, ","))
 		teams, err := GetTeamsHaveAccessToRepo(repo.OwnerID, repo.ID, ACCESS_MODE_WRITE)
 		if err != nil {
 			return fmt.Errorf("GetTeamsHaveAccessToRepo [org_id: %d, repo_id: %d]: %v", repo.OwnerID, repo.ID, err)
@@ -184,7 +184,7 @@ func UpdateOrgProtectBranch(repo *Repository, protectBranch *ProtectBranch, whit
 			}
 		}
 
-		protectBranch.WhitelistTeamIDs = strings.Join(base.Int64sToStrings(validTeamIDs), ",")
+		protectBranch.WhitelistTeamIDs = strings.Join(tool.Int64sToStrings(validTeamIDs), ",")
 	}
 
 	// Make sure protectBranch.ID is not 0 for whitelists

+ 2 - 2
models/ssh_key.go

@@ -23,7 +23,7 @@ import (
 	"golang.org/x/crypto/ssh"
 	log "gopkg.in/clog.v1"
 
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/process"
 	"github.com/gogits/gogs/pkg/setting"
 )
@@ -484,7 +484,7 @@ func deletePublicKeys(e *xorm.Session, keyIDs ...int64) error {
 		return nil
 	}
 
-	_, err := e.In("id", strings.Join(base.Int64sToStrings(keyIDs), ",")).Delete(new(PublicKey))
+	_, err := e.In("id", strings.Join(tool.Int64sToStrings(keyIDs), ",")).Delete(new(PublicKey))
 	return err
 }
 

+ 2 - 2
models/token.go

@@ -10,7 +10,7 @@ import (
 	"github.com/go-xorm/xorm"
 	gouuid "github.com/satori/go.uuid"
 
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 )
 
 // AccessToken represents a personal access token.
@@ -49,7 +49,7 @@ func (t *AccessToken) AfterSet(colName string, _ xorm.Cell) {
 
 // NewAccessToken creates new access token.
 func NewAccessToken(t *AccessToken) error {
-	t.Sha1 = base.EncodeSha1(gouuid.NewV4().String())
+	t.Sha1 = tool.EncodeSha1(gouuid.NewV4().String())
 	_, err := x.Insert(t)
 	return err
 }

+ 16 - 16
models/user.go

@@ -31,7 +31,7 @@ import (
 
 	"github.com/gogits/gogs/models/errors"
 	"github.com/gogits/gogs/pkg/avatar"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/setting"
 )
 
@@ -191,7 +191,7 @@ func (u *User) HTMLURL() string {
 
 // GenerateEmailActivateCode generates an activate code based on user information and given e-mail.
 func (u *User) GenerateEmailActivateCode(email string) string {
-	code := base.CreateTimeLimitCode(
+	code := tool.CreateTimeLimitCode(
 		com.ToStr(u.ID)+email+u.LowerName+u.Passwd+u.Rands,
 		setting.Service.ActiveCodeLives, nil)
 
@@ -262,7 +262,7 @@ func (u *User) RelAvatarLink() string {
 
 		return setting.AppSubUrl + "/avatars/" + com.ToStr(u.ID)
 	}
-	return base.AvatarLink(u.AvatarEmail)
+	return tool.AvatarLink(u.AvatarEmail)
 }
 
 // AvatarLink returns user avatar absolute link.
@@ -462,7 +462,7 @@ func (u *User) DisplayName() string {
 }
 
 func (u *User) ShortName(length int) string {
-	return base.EllipsisString(u.Name, length)
+	return tool.EllipsisString(u.Name, length)
 }
 
 // IsMailable checks if a user is elegible
@@ -484,7 +484,7 @@ func IsUserExist(uid int64, name string) (bool, error) {
 
 // GetUserSalt returns a ramdom user salt token.
 func GetUserSalt() (string, error) {
-	return base.GetRandomString(10)
+	return tool.GetRandomString(10)
 }
 
 // NewGhostUser creates and returns a fake user for someone has deleted his/her account.
@@ -553,7 +553,7 @@ func CreateUser(u *User) (err error) {
 
 	u.LowerName = strings.ToLower(u.Name)
 	u.AvatarEmail = u.Email
-	u.Avatar = base.HashEmail(u.AvatarEmail)
+	u.Avatar = tool.HashEmail(u.AvatarEmail)
 	if u.Rands, err = GetUserSalt(); err != nil {
 		return err
 	}
@@ -596,12 +596,12 @@ func Users(page, pageSize int) ([]*User, error) {
 
 // get user by erify code
 func getVerifyUser(code string) (user *User) {
-	if len(code) <= base.TimeLimitCodeLength {
+	if len(code) <= tool.TimeLimitCodeLength {
 		return nil
 	}
 
 	// use tail hex username query user
-	hexStr := code[base.TimeLimitCodeLength:]
+	hexStr := code[tool.TimeLimitCodeLength:]
 	if b, err := hex.DecodeString(hexStr); err == nil {
 		if user, err = GetUserByName(string(b)); user != nil {
 			return user
@@ -618,10 +618,10 @@ func VerifyUserActiveCode(code string) (user *User) {
 
 	if user = getVerifyUser(code); user != nil {
 		// time limit code
-		prefix := code[:base.TimeLimitCodeLength]
+		prefix := code[:tool.TimeLimitCodeLength]
 		data := com.ToStr(user.ID) + user.Email + user.LowerName + user.Passwd + user.Rands
 
-		if base.VerifyTimeLimitCode(data, minutes, prefix) {
+		if tool.VerifyTimeLimitCode(data, minutes, prefix) {
 			return user
 		}
 	}
@@ -634,10 +634,10 @@ func VerifyActiveEmailCode(code, email string) *EmailAddress {
 
 	if user := getVerifyUser(code); user != nil {
 		// time limit code
-		prefix := code[:base.TimeLimitCodeLength]
+		prefix := code[:tool.TimeLimitCodeLength]
 		data := com.ToStr(user.ID) + email + user.LowerName + user.Passwd + user.Rands
 
-		if base.VerifyTimeLimitCode(data, minutes, prefix) {
+		if tool.VerifyTimeLimitCode(data, minutes, prefix) {
 			emailAddress := &EmailAddress{Email: email}
 			if has, _ := x.Get(emailAddress); has {
 				return emailAddress
@@ -696,13 +696,13 @@ func updateUser(e Engine, u *User) error {
 		if len(u.AvatarEmail) == 0 {
 			u.AvatarEmail = u.Email
 		}
-		u.Avatar = base.HashEmail(u.AvatarEmail)
+		u.Avatar = tool.HashEmail(u.AvatarEmail)
 	}
 
 	u.LowerName = strings.ToLower(u.Name)
-	u.Location = base.TruncateString(u.Location, 255)
-	u.Website = base.TruncateString(u.Website, 255)
-	u.Description = base.TruncateString(u.Description, 255)
+	u.Location = tool.TruncateString(u.Location, 255)
+	u.Website = tool.TruncateString(u.Website, 255)
+	u.Description = tool.TruncateString(u.Description, 255)
 
 	_, err := e.Id(u.ID).AllCols().Update(u)
 	return err

+ 2 - 2
pkg/auth/auth.go

@@ -15,7 +15,7 @@ import (
 
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/models/errors"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/setting"
 )
 
@@ -122,7 +122,7 @@ func SignedInUser(ctx *macaron.Context, sess session.Store) (*models.User, bool)
 		if len(baHead) > 0 {
 			auths := strings.Fields(baHead)
 			if len(auths) == 2 && auths[0] == "Basic" {
-				uname, passwd, _ := base.BasicAuthDecode(auths[1])
+				uname, passwd, _ := tool.BasicAuthDecode(auths[1])
 
 				u, err := models.UserSignIn(uname, passwd)
 				if err != nil {

+ 2 - 2
pkg/context/api.go

@@ -12,7 +12,7 @@ import (
 	log "gopkg.in/clog.v1"
 	"gopkg.in/macaron.v1"
 
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/setting"
 )
 
@@ -37,7 +37,7 @@ func (ctx *APIContext) Error(status int, title string, obj interface{}) {
 
 	ctx.JSON(status, map[string]string{
 		"message": message,
-		"url":     base.DOC_URL,
+		"url":     tool.DOC_URL,
 	})
 }
 

+ 5 - 5
pkg/context/context.go

@@ -21,7 +21,7 @@ import (
 
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/pkg/auth"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/form"
 	"github.com/gogits/gogs/pkg/setting"
 )
@@ -80,18 +80,18 @@ func (ctx *Context) HasValue(name string) bool {
 }
 
 // HTML responses template with given status.
-func (ctx *Context) HTML(status int, name base.TplName) {
+func (ctx *Context) HTML(status int, name tool.TplName) {
 	log.Trace("Template: %s", name)
 	ctx.Context.HTML(status, string(name))
 }
 
 // Success responses template with status http.StatusOK.
-func (c *Context) Success(name base.TplName) {
+func (c *Context) Success(name tool.TplName) {
 	c.HTML(http.StatusOK, name)
 }
 
 // RenderWithErr used for page has form validation but need to prompt error to users.
-func (ctx *Context) RenderWithErr(msg string, tpl base.TplName, f interface{}) {
+func (ctx *Context) RenderWithErr(msg string, tpl tool.TplName, f interface{}) {
 	if f != nil {
 		form.Assign(f, ctx.Data)
 	}
@@ -112,7 +112,7 @@ func (ctx *Context) Handle(status int, title string, err error) {
 			ctx.Data["ErrorMsg"] = err
 		}
 	}
-	ctx.HTML(status, base.TplName(fmt.Sprintf("status/%d", status)))
+	ctx.HTML(status, tool.TplName(fmt.Sprintf("status/%d", status)))
 }
 
 // NotFound renders the 404 page.

+ 10 - 10
pkg/mailer/mail.go

@@ -12,21 +12,21 @@ import (
 	"gopkg.in/gomail.v2"
 	"gopkg.in/macaron.v1"
 
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/markup"
 	"github.com/gogits/gogs/pkg/setting"
 )
 
 const (
-	MAIL_AUTH_ACTIVATE        base.TplName = "auth/activate"
-	MAIL_AUTH_ACTIVATE_EMAIL  base.TplName = "auth/activate_email"
-	MAIL_AUTH_RESET_PASSWORD  base.TplName = "auth/reset_passwd"
-	MAIL_AUTH_REGISTER_NOTIFY base.TplName = "auth/register_notify"
+	MAIL_AUTH_ACTIVATE        tool.TplName = "auth/activate"
+	MAIL_AUTH_ACTIVATE_EMAIL  tool.TplName = "auth/activate_email"
+	MAIL_AUTH_RESET_PASSWORD  tool.TplName = "auth/reset_passwd"
+	MAIL_AUTH_REGISTER_NOTIFY tool.TplName = "auth/register_notify"
 
-	MAIL_ISSUE_COMMENT base.TplName = "issue/comment"
-	MAIL_ISSUE_MENTION base.TplName = "issue/mention"
+	MAIL_ISSUE_COMMENT tool.TplName = "issue/comment"
+	MAIL_ISSUE_MENTION tool.TplName = "issue/mention"
 
-	MAIL_NOTIFY_COLLABORATOR base.TplName = "notify/collaborator"
+	MAIL_NOTIFY_COLLABORATOR tool.TplName = "notify/collaborator"
 )
 
 type MailRender interface {
@@ -79,7 +79,7 @@ type Issue interface {
 	HTMLURL() string
 }
 
-func SendUserMail(c *macaron.Context, u User, tpl base.TplName, code, subject, info string) {
+func SendUserMail(c *macaron.Context, u User, tpl tool.TplName, code, subject, info string) {
 	data := map[string]interface{}{
 		"Username":          u.DisplayName(),
 		"ActiveCodeLives":   setting.Service.ActiveCodeLives / 60,
@@ -172,7 +172,7 @@ func composeTplData(subject, body, link string) map[string]interface{} {
 	return data
 }
 
-func composeIssueMessage(issue Issue, repo Repository, doer User, tplName base.TplName, tos []string, info string) *Message {
+func composeIssueMessage(issue Issue, repo Repository, doer User, tplName tool.TplName, tos []string, info string) *Message {
 	subject := issue.MailSubject()
 	body := string(markup.RenderSpecialLink([]byte(issue.Content()), repo.HTMLURL(), repo.ComposeMetas()))
 	data := composeTplData(subject, body, issue.HTMLURL())

+ 2 - 2
pkg/markup/markdown.go

@@ -14,7 +14,7 @@ import (
 
 	"github.com/russross/blackfriday"
 
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/setting"
 )
 
@@ -72,7 +72,7 @@ func (r *MarkdownRenderer) AutoLink(out *bytes.Buffer, link []byte, kind int) {
 			if j == -1 {
 				j = len(m)
 			}
-			out.WriteString(fmt.Sprintf(` <code><a href="%s">%s</a></code>`, m, base.ShortSha(string(m[i+7:j]))))
+			out.WriteString(fmt.Sprintf(` <code><a href="%s">%s</a></code>`, m, tool.ShortSha(string(m[i+7:j]))))
 			return
 		}
 

+ 2 - 2
pkg/markup/markup.go

@@ -14,7 +14,7 @@ import (
 	"github.com/Unknwon/com"
 	"golang.org/x/net/html"
 
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/setting"
 )
 
@@ -140,7 +140,7 @@ func RenderSha1CurrentPattern(rawBytes []byte, urlPrefix string) []byte {
 		if com.StrTo(m).MustInt() > 0 {
 			return m
 		}
-		return fmt.Sprintf(`<a href="%s/commit/%s"><code>%s</code></a>`, urlPrefix, m, base.ShortSha(string(m)))
+		return fmt.Sprintf(`<a href="%s/commit/%s"><code>%s</code></a>`, urlPrefix, m, tool.ShortSha(string(m)))
 	}))
 }
 

+ 15 - 15
pkg/template/template.go

@@ -22,7 +22,7 @@ import (
 	"gopkg.in/editorconfig/editorconfig-core-go.v1"
 
 	"github.com/gogits/gogs/models"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/markup"
 	"github.com/gogits/gogs/pkg/setting"
 )
@@ -59,14 +59,14 @@ func NewFuncMap() []template.FuncMap {
 		"LoadTimes": func(startTime time.Time) string {
 			return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms"
 		},
-		"AvatarLink":   base.AvatarLink,
+		"AvatarLink":   tool.AvatarLink,
 		"Safe":         Safe,
 		"Sanitize":     bluemonday.UGCPolicy().Sanitize,
 		"Str2html":     Str2html,
-		"TimeSince":    base.TimeSince,
-		"RawTimeSince": base.RawTimeSince,
-		"FileSize":     base.FileSize,
-		"Subtract":     base.Subtract,
+		"TimeSince":    tool.TimeSince,
+		"RawTimeSince": tool.RawTimeSince,
+		"FileSize":     tool.FileSize,
+		"Subtract":     tool.Subtract,
 		"Add": func(a, b int) int {
 			return a + b
 		},
@@ -91,13 +91,13 @@ func NewFuncMap() []template.FuncMap {
 			}
 			return str[start:end]
 		},
-		"Join":              strings.Join,
-		"EllipsisString":    base.EllipsisString,
-		"DiffTypeToStr":     DiffTypeToStr,
-		"DiffLineTypeToStr": DiffLineTypeToStr,
-		"Sha1":              Sha1,
-		"ShortSha":          base.ShortSha,
-		"MD5":               base.EncodeMD5,
+		"Join":                  strings.Join,
+		"EllipsisString":        tool.EllipsisString,
+		"DiffTypeToStr":         DiffTypeToStr,
+		"DiffLineTypeToStr":     DiffLineTypeToStr,
+		"Sha1":                  Sha1,
+		"ShortSha":              tool.ShortSha,
+		"MD5":                   tool.EncodeMD5,
 		"ActionContent2Commits": ActionContent2Commits,
 		"EscapePound":           EscapePound,
 		"RenderCommitMessage":   RenderCommitMessage,
@@ -142,11 +142,11 @@ func List(l *list.List) chan interface{} {
 }
 
 func Sha1(str string) string {
-	return base.EncodeSha1(str)
+	return tool.EncodeSha1(str)
 }
 
 func ToUTF8WithErr(content []byte) (error, string) {
-	charsetLabel, err := base.DetectEncoding(content)
+	charsetLabel, err := tool.DetectEncoding(content)
 	if err != nil {
 		return err, ""
 	} else if charsetLabel == "UTF-8" {

+ 1 - 1
pkg/base/base.go → pkg/tool/base.go

@@ -2,7 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
-package base
+package tool
 
 const DOC_URL = "https://github.com/gogits/go-gogs-client/wiki"
 

+ 1 - 1
pkg/base/file.go → pkg/tool/file.go

@@ -2,7 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
-package base
+package tool
 
 import (
 	"fmt"

+ 1 - 1
pkg/base/tool.go → pkg/tool/tool.go

@@ -2,7 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
-package base
+package tool
 
 import (
 	"crypto/md5"

+ 24 - 24
routers/admin/admin.go

@@ -15,7 +15,7 @@ import (
 	"gopkg.in/macaron.v1"
 
 	"github.com/gogits/gogs/models"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/cron"
 	"github.com/gogits/gogs/pkg/mailer"
@@ -24,9 +24,9 @@ import (
 )
 
 const (
-	DASHBOARD base.TplName = "admin/dashboard"
-	CONFIG    base.TplName = "admin/config"
-	MONITOR   base.TplName = "admin/monitor"
+	DASHBOARD tool.TplName = "admin/dashboard"
+	CONFIG    tool.TplName = "admin/config"
+	MONITOR   tool.TplName = "admin/monitor"
 )
 
 var (
@@ -75,37 +75,37 @@ var sysStatus struct {
 }
 
 func updateSystemStatus() {
-	sysStatus.Uptime = base.TimeSincePro(startTime)
+	sysStatus.Uptime = tool.TimeSincePro(startTime)
 
 	m := new(runtime.MemStats)
 	runtime.ReadMemStats(m)
 	sysStatus.NumGoroutine = runtime.NumGoroutine()
 
-	sysStatus.MemAllocated = base.FileSize(int64(m.Alloc))
-	sysStatus.MemTotal = base.FileSize(int64(m.TotalAlloc))
-	sysStatus.MemSys = base.FileSize(int64(m.Sys))
+	sysStatus.MemAllocated = tool.FileSize(int64(m.Alloc))
+	sysStatus.MemTotal = tool.FileSize(int64(m.TotalAlloc))
+	sysStatus.MemSys = tool.FileSize(int64(m.Sys))
 	sysStatus.Lookups = m.Lookups
 	sysStatus.MemMallocs = m.Mallocs
 	sysStatus.MemFrees = m.Frees
 
-	sysStatus.HeapAlloc = base.FileSize(int64(m.HeapAlloc))
-	sysStatus.HeapSys = base.FileSize(int64(m.HeapSys))
-	sysStatus.HeapIdle = base.FileSize(int64(m.HeapIdle))
-	sysStatus.HeapInuse = base.FileSize(int64(m.HeapInuse))
-	sysStatus.HeapReleased = base.FileSize(int64(m.HeapReleased))
+	sysStatus.HeapAlloc = tool.FileSize(int64(m.HeapAlloc))
+	sysStatus.HeapSys = tool.FileSize(int64(m.HeapSys))
+	sysStatus.HeapIdle = tool.FileSize(int64(m.HeapIdle))
+	sysStatus.HeapInuse = tool.FileSize(int64(m.HeapInuse))
+	sysStatus.HeapReleased = tool.FileSize(int64(m.HeapReleased))
 	sysStatus.HeapObjects = m.HeapObjects
 
-	sysStatus.StackInuse = base.FileSize(int64(m.StackInuse))
-	sysStatus.StackSys = base.FileSize(int64(m.StackSys))
-	sysStatus.MSpanInuse = base.FileSize(int64(m.MSpanInuse))
-	sysStatus.MSpanSys = base.FileSize(int64(m.MSpanSys))
-	sysStatus.MCacheInuse = base.FileSize(int64(m.MCacheInuse))
-	sysStatus.MCacheSys = base.FileSize(int64(m.MCacheSys))
-	sysStatus.BuckHashSys = base.FileSize(int64(m.BuckHashSys))
-	sysStatus.GCSys = base.FileSize(int64(m.GCSys))
-	sysStatus.OtherSys = base.FileSize(int64(m.OtherSys))
-
-	sysStatus.NextGC = base.FileSize(int64(m.NextGC))
+	sysStatus.StackInuse = tool.FileSize(int64(m.StackInuse))
+	sysStatus.StackSys = tool.FileSize(int64(m.StackSys))
+	sysStatus.MSpanInuse = tool.FileSize(int64(m.MSpanInuse))
+	sysStatus.MSpanSys = tool.FileSize(int64(m.MSpanSys))
+	sysStatus.MCacheInuse = tool.FileSize(int64(m.MCacheInuse))
+	sysStatus.MCacheSys = tool.FileSize(int64(m.MCacheSys))
+	sysStatus.BuckHashSys = tool.FileSize(int64(m.BuckHashSys))
+	sysStatus.GCSys = tool.FileSize(int64(m.GCSys))
+	sysStatus.OtherSys = tool.FileSize(int64(m.OtherSys))
+
+	sysStatus.NextGC = tool.FileSize(int64(m.NextGC))
 	sysStatus.LastGC = fmt.Sprintf("%.1fs", float64(time.Now().UnixNano()-int64(m.LastGC))/1000/1000/1000)
 	sysStatus.PauseTotalNs = fmt.Sprintf("%.1fs", float64(m.PauseTotalNs)/1000/1000/1000)
 	sysStatus.PauseNs = fmt.Sprintf("%.3fs", float64(m.PauseNs[(m.NumGC+255)%256])/1000/1000/1000)

+ 4 - 4
routers/admin/auths.go

@@ -13,16 +13,16 @@ import (
 
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/pkg/auth/ldap"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/form"
 	"github.com/gogits/gogs/pkg/setting"
 )
 
 const (
-	AUTHS     base.TplName = "admin/auth/list"
-	AUTH_NEW  base.TplName = "admin/auth/new"
-	AUTH_EDIT base.TplName = "admin/auth/edit"
+	AUTHS     tool.TplName = "admin/auth/list"
+	AUTH_NEW  tool.TplName = "admin/auth/new"
+	AUTH_EDIT tool.TplName = "admin/auth/edit"
 )
 
 func Authentications(ctx *context.Context) {

+ 2 - 2
routers/admin/notice.go

@@ -10,13 +10,13 @@ import (
 	log "gopkg.in/clog.v1"
 
 	"github.com/gogits/gogs/models"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/setting"
 )
 
 const (
-	NOTICES base.TplName = "admin/notice"
+	NOTICES tool.TplName = "admin/notice"
 )
 
 func Notices(ctx *context.Context) {

+ 2 - 2
routers/admin/orgs.go

@@ -6,14 +6,14 @@ package admin
 
 import (
 	"github.com/gogits/gogs/models"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/setting"
 	"github.com/gogits/gogs/routers"
 )
 
 const (
-	ORGS base.TplName = "admin/org/list"
+	ORGS tool.TplName = "admin/org/list"
 )
 
 func Organizations(ctx *context.Context) {

+ 2 - 2
routers/admin/repos.go

@@ -9,13 +9,13 @@ import (
 	log "gopkg.in/clog.v1"
 
 	"github.com/gogits/gogs/models"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/setting"
 )
 
 const (
-	REPOS base.TplName = "admin/repo/list"
+	REPOS tool.TplName = "admin/repo/list"
 )
 
 func Repos(ctx *context.Context) {

+ 4 - 4
routers/admin/users.go

@@ -11,7 +11,7 @@ import (
 	log "gopkg.in/clog.v1"
 
 	"github.com/gogits/gogs/models"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/form"
 	"github.com/gogits/gogs/pkg/mailer"
@@ -20,9 +20,9 @@ import (
 )
 
 const (
-	USERS     base.TplName = "admin/user/list"
-	USER_NEW  base.TplName = "admin/user/new"
-	USER_EDIT base.TplName = "admin/user/edit"
+	USERS     tool.TplName = "admin/user/list"
+	USER_NEW  tool.TplName = "admin/user/new"
+	USER_EDIT tool.TplName = "admin/user/edit"
 )
 
 func Users(ctx *context.Context) {

+ 2 - 2
routers/dev/template.go

@@ -6,7 +6,7 @@ package dev
 
 import (
 	"github.com/gogits/gogs/models"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/setting"
 )
@@ -21,5 +21,5 @@ func TemplatePreview(ctx *context.Context) {
 	ctx.Data["ResetPwdCodeLives"] = setting.Service.ResetPwdCodeLives / 60
 	ctx.Data["CurDbValue"] = ""
 
-	ctx.HTML(200, base.TplName(ctx.Params("*")))
+	ctx.HTML(200, tool.TplName(ctx.Params("*")))
 }

+ 6 - 6
routers/home.go

@@ -8,17 +8,17 @@ import (
 	"github.com/Unknwon/paginater"
 
 	"github.com/gogits/gogs/models"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/setting"
 	"github.com/gogits/gogs/routers/user"
 )
 
 const (
-	HOME                  base.TplName = "home"
-	EXPLORE_REPOS         base.TplName = "explore/repos"
-	EXPLORE_USERS         base.TplName = "explore/users"
-	EXPLORE_ORGANIZATIONS base.TplName = "explore/organizations"
+	HOME                  tool.TplName = "home"
+	EXPLORE_REPOS         tool.TplName = "explore/repos"
+	EXPLORE_USERS         tool.TplName = "explore/users"
+	EXPLORE_ORGANIZATIONS tool.TplName = "explore/organizations"
 )
 
 func Home(ctx *context.Context) {
@@ -84,7 +84,7 @@ type UserSearchOptions struct {
 	Ranger   func(int, int) ([]*models.User, error)
 	PageSize int
 	OrderBy  string
-	TplName  base.TplName
+	TplName  tool.TplName
 }
 
 func RenderUserSearch(ctx *context.Context, opts *UserSearchOptions) {

+ 3 - 3
routers/install.go

@@ -21,7 +21,7 @@ import (
 	"github.com/gogits/git-module"
 
 	"github.com/gogits/gogs/models"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/cron"
 	"github.com/gogits/gogs/pkg/form"
@@ -34,7 +34,7 @@ import (
 )
 
 const (
-	INSTALL base.TplName = "install"
+	INSTALL tool.TplName = "install"
 )
 
 func checkRunMode() {
@@ -344,7 +344,7 @@ func InstallPost(ctx *context.Context, f form.Install) {
 	cfg.Section("log").Key("ROOT_PATH").SetValue(f.LogRootPath)
 
 	cfg.Section("security").Key("INSTALL_LOCK").SetValue("true")
-	secretKey, err := base.GetRandomString(15)
+	secretKey, err := tool.GetRandomString(15)
 	if err != nil {
 		ctx.RenderWithErr(ctx.Tr("install.secret_key_failed", err), INSTALL, &f)
 		return

+ 3 - 3
routers/org/members.go

@@ -10,14 +10,14 @@ import (
 
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/models/errors"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/setting"
 )
 
 const (
-	MEMBERS       base.TplName = "org/member/members"
-	MEMBER_INVITE base.TplName = "org/member/invite"
+	MEMBERS       tool.TplName = "org/member/members"
+	MEMBER_INVITE tool.TplName = "org/member/invite"
 )
 
 func Members(ctx *context.Context) {

+ 2 - 2
routers/org/org.go

@@ -9,13 +9,13 @@ import (
 
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/pkg/form"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/setting"
 )
 
 const (
-	CREATE base.TplName = "org/create"
+	CREATE tool.TplName = "org/create"
 )
 
 func Create(ctx *context.Context) {

+ 4 - 4
routers/org/setting.go

@@ -11,7 +11,7 @@ import (
 
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/models/errors"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/form"
 	"github.com/gogits/gogs/pkg/setting"
@@ -19,9 +19,9 @@ import (
 )
 
 const (
-	SETTINGS_OPTIONS  base.TplName = "org/settings/options"
-	SETTINGS_DELETE   base.TplName = "org/settings/delete"
-	SETTINGS_WEBHOOKS base.TplName = "org/settings/webhooks"
+	SETTINGS_OPTIONS  tool.TplName = "org/settings/options"
+	SETTINGS_DELETE   tool.TplName = "org/settings/delete"
+	SETTINGS_WEBHOOKS tool.TplName = "org/settings/webhooks"
 )
 
 func Settings(ctx *context.Context) {

+ 5 - 5
routers/org/teams.go

@@ -12,16 +12,16 @@ import (
 
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/models/errors"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/form"
 )
 
 const (
-	TEAMS             base.TplName = "org/team/teams"
-	TEAM_NEW          base.TplName = "org/team/new"
-	TEAM_MEMBERS      base.TplName = "org/team/members"
-	TEAM_REPOSITORIES base.TplName = "org/team/repositories"
+	TEAMS             tool.TplName = "org/team/teams"
+	TEAM_NEW          tool.TplName = "org/team/new"
+	TEAM_MEMBERS      tool.TplName = "org/team/members"
+	TEAM_REPOSITORIES tool.TplName = "org/team/repositories"
 )
 
 func Teams(ctx *context.Context) {

+ 3 - 3
routers/repo/branch.go

@@ -12,13 +12,13 @@ import (
 	"github.com/gogits/git-module"
 
 	"github.com/gogits/gogs/models"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 )
 
 const (
-	BRANCHES_OVERVIEW base.TplName = "repo/branches/overview"
-	BRANCHES_ALL      base.TplName = "repo/branches/all"
+	BRANCHES_OVERVIEW tool.TplName = "repo/branches/overview"
+	BRANCHES_ALL      tool.TplName = "repo/branches/all"
 )
 
 type Branch struct {

+ 5 - 5
routers/repo/commit.go

@@ -11,14 +11,14 @@ import (
 	"github.com/gogits/git-module"
 
 	"github.com/gogits/gogs/models"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/setting"
 )
 
 const (
-	COMMITS base.TplName = "repo/commits"
-	DIFF    base.TplName = "repo/diff/page"
+	COMMITS tool.TplName = "repo/commits"
+	DIFF    tool.TplName = "repo/diff/page"
 )
 
 func RefCommits(ctx *context.Context) {
@@ -165,7 +165,7 @@ func Diff(ctx *context.Context) {
 	ctx.Data["Username"] = userName
 	ctx.Data["Reponame"] = repoName
 	ctx.Data["IsImageFile"] = commit.IsImageFile
-	ctx.Data["Title"] = commit.Summary() + " · " + base.ShortSha(commitID)
+	ctx.Data["Title"] = commit.Summary() + " · " + tool.ShortSha(commitID)
 	ctx.Data["Commit"] = commit
 	ctx.Data["Author"] = models.ValidateCommitWithEmail(commit)
 	ctx.Data["Diff"] = diff
@@ -228,7 +228,7 @@ func CompareDiff(ctx *context.Context) {
 	ctx.Data["Username"] = userName
 	ctx.Data["Reponame"] = repoName
 	ctx.Data["IsImageFile"] = commit.IsImageFile
-	ctx.Data["Title"] = "Comparing " + base.ShortSha(beforeCommitID) + "..." + base.ShortSha(afterCommitID) + " · " + userName + "/" + repoName
+	ctx.Data["Title"] = "Comparing " + tool.ShortSha(beforeCommitID) + "..." + tool.ShortSha(afterCommitID) + " · " + userName + "/" + repoName
 	ctx.Data["Commit"] = commit
 	ctx.Data["Diff"] = diff
 	ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0

+ 3 - 3
routers/repo/download.go

@@ -10,7 +10,7 @@ import (
 
 	"github.com/gogits/git-module"
 
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/setting"
 )
@@ -22,8 +22,8 @@ func ServeData(ctx *context.Context, name string, reader io.Reader) error {
 		buf = buf[:n]
 	}
 
-	if !base.IsTextFile(buf) {
-		if !base.IsImageFile(buf) {
+	if !tool.IsTextFile(buf) {
+		if !tool.IsImageFile(buf) {
 			ctx.Resp.Header().Set("Content-Disposition", "attachment; filename=\""+name+"\"")
 			ctx.Resp.Header().Set("Content-Transfer-Encoding", "binary")
 		}

+ 6 - 6
routers/repo/editor.go

@@ -15,7 +15,7 @@ import (
 
 	"github.com/gogits/git-module"
 	"github.com/gogits/gogs/models"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/form"
 	"github.com/gogits/gogs/pkg/setting"
@@ -23,10 +23,10 @@ import (
 )
 
 const (
-	EDIT_FILE         base.TplName = "repo/editor/edit"
-	EDIT_DIFF_PREVIEW base.TplName = "repo/editor/diff_preview"
-	DELETE_FILE       base.TplName = "repo/editor/delete"
-	UPLOAD_FILE       base.TplName = "repo/editor/upload"
+	EDIT_FILE         tool.TplName = "repo/editor/edit"
+	EDIT_DIFF_PREVIEW tool.TplName = "repo/editor/diff_preview"
+	DELETE_FILE       tool.TplName = "repo/editor/delete"
+	UPLOAD_FILE       tool.TplName = "repo/editor/upload"
 )
 
 // getParentTreeFields returns list of parent tree names and corresponding tree paths
@@ -80,7 +80,7 @@ func editFile(ctx *context.Context, isNewFile bool) {
 		buf = buf[:n]
 
 		// Only text file are editable online.
-		if !base.IsTextFile(buf) {
+		if !tool.IsTextFile(buf) {
 			ctx.Handle(404, "", nil)
 			return
 		}

+ 3 - 3
routers/repo/http.go

@@ -23,7 +23,7 @@ import (
 
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/models/errors"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/setting"
 )
@@ -106,7 +106,7 @@ func HTTPContexter() macaron.Handler {
 			askCredentials(c, http.StatusUnauthorized, "")
 			return
 		}
-		authUsername, authPassword, err := base.BasicAuthDecode(auths[1])
+		authUsername, authPassword, err := tool.BasicAuthDecode(auths[1])
 		if err != nil {
 			askCredentials(c, http.StatusUnauthorized, "")
 			return
@@ -229,7 +229,7 @@ func ComposeHookEnvs(opts ComposeHookEnvsOptions) []string {
 		ENV_AUTH_USER_NAME + "=" + opts.AuthUser.Name,
 		ENV_AUTH_USER_EMAIL + "=" + opts.AuthUser.Email,
 		ENV_REPO_OWNER_NAME + "=" + opts.OwnerName,
-		ENV_REPO_OWNER_SALT_MD5 + "=" + base.EncodeMD5(opts.OwnerSalt),
+		ENV_REPO_OWNER_SALT_MD5 + "=" + tool.EncodeMD5(opts.OwnerSalt),
 		ENV_REPO_ID + "=" + com.ToStr(opts.RepoID),
 		ENV_REPO_NAME + "=" + opts.RepoName,
 		ENV_REPO_CUSTOM_HOOKS_PATH + "=" + path.Join(opts.RepoPath, "custom_hooks"),

+ 10 - 10
routers/repo/issue.go

@@ -19,7 +19,7 @@ import (
 
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/models/errors"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/form"
 	"github.com/gogits/gogs/pkg/markup"
@@ -27,15 +27,15 @@ import (
 )
 
 const (
-	ISSUES     base.TplName = "repo/issue/list"
-	ISSUE_NEW  base.TplName = "repo/issue/new"
-	ISSUE_VIEW base.TplName = "repo/issue/view"
+	ISSUES     tool.TplName = "repo/issue/list"
+	ISSUE_NEW  tool.TplName = "repo/issue/new"
+	ISSUE_VIEW tool.TplName = "repo/issue/view"
 
-	LABELS base.TplName = "repo/issue/labels"
+	LABELS tool.TplName = "repo/issue/labels"
 
-	MILESTONE      base.TplName = "repo/issue/milestones"
-	MILESTONE_NEW  base.TplName = "repo/issue/milestone_new"
-	MILESTONE_EDIT base.TplName = "repo/issue/milestone_edit"
+	MILESTONE      tool.TplName = "repo/issue/milestones"
+	MILESTONE_NEW  tool.TplName = "repo/issue/milestone_new"
+	MILESTONE_EDIT tool.TplName = "repo/issue/milestone_edit"
 
 	ISSUE_TEMPLATE_KEY = "IssueTemplate"
 )
@@ -371,8 +371,8 @@ func ValidateRepoMetas(ctx *context.Context, f form.NewIssue) ([]int64, int64, i
 	}
 
 	// Check labels.
-	labelIDs := base.StringsToInt64s(strings.Split(f.LabelIDs, ","))
-	labelIDMark := base.Int64sToMap(labelIDs)
+	labelIDs := tool.StringsToInt64s(strings.Split(f.LabelIDs, ","))
+	labelIDMark := tool.Int64sToMap(labelIDs)
 	hasSelected := false
 	for i := range labels {
 		if labelIDMark[labels[i].ID] {

+ 6 - 6
routers/repo/pull.go

@@ -16,17 +16,17 @@ import (
 
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/models/errors"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/form"
 	"github.com/gogits/gogs/pkg/setting"
 )
 
 const (
-	FORK         base.TplName = "repo/pulls/fork"
-	COMPARE_PULL base.TplName = "repo/pulls/compare"
-	PULL_COMMITS base.TplName = "repo/pulls/commits"
-	PULL_FILES   base.TplName = "repo/pulls/files"
+	FORK         tool.TplName = "repo/pulls/fork"
+	COMPARE_PULL tool.TplName = "repo/pulls/compare"
+	PULL_COMMITS tool.TplName = "repo/pulls/commits"
+	PULL_FILES   tool.TplName = "repo/pulls/files"
 
 	PULL_REQUEST_TEMPLATE_KEY = "PullRequestTemplate"
 )
@@ -738,7 +738,7 @@ func TriggerTask(ctx *context.Context) {
 	if ctx.Written() {
 		return
 	}
-	if secret != base.EncodeMD5(owner.Salt) {
+	if secret != tool.EncodeMD5(owner.Salt) {
 		ctx.Error(404)
 		log.Trace("TriggerTask [%s/%s]: invalid secret", owner.Name, repo.Name)
 		return

+ 3 - 3
routers/repo/release.go

@@ -11,7 +11,7 @@ import (
 	log "gopkg.in/clog.v1"
 
 	"github.com/gogits/gogs/models"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/form"
 	"github.com/gogits/gogs/pkg/markup"
@@ -19,8 +19,8 @@ import (
 )
 
 const (
-	RELEASES    base.TplName = "repo/release/list"
-	RELEASE_NEW base.TplName = "repo/release/new"
+	RELEASES    tool.TplName = "repo/release/list"
+	RELEASE_NEW tool.TplName = "repo/release/new"
 )
 
 // calReleaseNumCommitsBehind calculates given release has how many commits behind release target.

+ 5 - 5
routers/repo/repo.go

@@ -17,15 +17,15 @@ import (
 
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/models/errors"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/form"
 	"github.com/gogits/gogs/pkg/setting"
 )
 
 const (
-	CREATE  base.TplName = "repo/create"
-	MIGRATE base.TplName = "repo/migrate"
+	CREATE  tool.TplName = "repo/create"
+	MIGRATE tool.TplName = "repo/migrate"
 )
 
 func MustBeNotBare(ctx *context.Context) {
@@ -85,7 +85,7 @@ func Create(ctx *context.Context) {
 	ctx.HTML(200, CREATE)
 }
 
-func handleCreateError(ctx *context.Context, owner *models.User, err error, name string, tpl base.TplName, form interface{}) {
+func handleCreateError(ctx *context.Context, owner *models.User, err error, name string, tpl tool.TplName, form interface{}) {
 	switch {
 	case models.IsErrReachLimitOfRepo(err):
 		ctx.RenderWithErr(ctx.Tr("repo.form.reach_limit_of_creation", owner.RepoCreationNum()), tpl, form)
@@ -323,7 +323,7 @@ func Download(ctx *context.Context) {
 		return
 	}
 
-	archivePath = path.Join(archivePath, base.ShortSha(commit.ID.String())+ext)
+	archivePath = path.Join(archivePath, tool.ShortSha(commit.ID.String())+ext)
 	if !com.IsFile(archivePath) {
 		if err := commit.CreateArchive(archivePath, archiveType); err != nil {
 			ctx.Handle(500, "Download -> CreateArchive "+archivePath, err)

+ 8 - 8
routers/repo/setting.go

@@ -15,7 +15,7 @@ import (
 
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/models/errors"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/form"
 	"github.com/gogits/gogs/pkg/mailer"
@@ -23,13 +23,13 @@ import (
 )
 
 const (
-	SETTINGS_OPTIONS          base.TplName = "repo/settings/options"
-	SETTINGS_COLLABORATION    base.TplName = "repo/settings/collaboration"
-	SETTINGS_BRANCHES         base.TplName = "repo/settings/branches"
-	SETTINGS_PROTECTED_BRANCH base.TplName = "repo/settings/protected_branch"
-	SETTINGS_GITHOOKS         base.TplName = "repo/settings/githooks"
-	SETTINGS_GITHOOK_EDIT     base.TplName = "repo/settings/githook_edit"
-	SETTINGS_DEPLOY_KEYS      base.TplName = "repo/settings/deploy_keys"
+	SETTINGS_OPTIONS          tool.TplName = "repo/settings/options"
+	SETTINGS_COLLABORATION    tool.TplName = "repo/settings/collaboration"
+	SETTINGS_BRANCHES         tool.TplName = "repo/settings/branches"
+	SETTINGS_PROTECTED_BRANCH tool.TplName = "repo/settings/protected_branch"
+	SETTINGS_GITHOOKS         tool.TplName = "repo/settings/githooks"
+	SETTINGS_GITHOOK_EDIT     tool.TplName = "repo/settings/githook_edit"
+	SETTINGS_DEPLOY_KEYS      tool.TplName = "repo/settings/deploy_keys"
 )
 
 func Settings(ctx *context.Context) {

+ 11 - 11
routers/repo/view.go

@@ -18,7 +18,7 @@ import (
 	"github.com/gogits/git-module"
 
 	"github.com/gogits/gogs/models"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/markup"
 	"github.com/gogits/gogs/pkg/setting"
@@ -27,10 +27,10 @@ import (
 )
 
 const (
-	BARE     base.TplName = "repo/bare"
-	HOME     base.TplName = "repo/home"
-	WATCHERS base.TplName = "repo/watchers"
-	FORKS    base.TplName = "repo/forks"
+	BARE     tool.TplName = "repo/bare"
+	HOME     tool.TplName = "repo/home"
+	WATCHERS tool.TplName = "repo/watchers"
+	FORKS    tool.TplName = "repo/forks"
 )
 
 func renderDirectory(ctx *context.Context, treeLink string) {
@@ -79,7 +79,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
 		n, _ := dataRc.Read(buf)
 		buf = buf[:n]
 
-		isTextFile := base.IsTextFile(buf)
+		isTextFile := tool.IsTextFile(buf)
 		ctx.Data["IsTextFile"] = isTextFile
 		ctx.Data["FileName"] = readmeFile.Name()
 		if isTextFile {
@@ -134,7 +134,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
 	n, _ := dataRc.Read(buf)
 	buf = buf[:n]
 
-	isTextFile := base.IsTextFile(buf)
+	isTextFile := tool.IsTextFile(buf)
 	ctx.Data["IsTextFile"] = isTextFile
 
 	// Assume file is not editable first.
@@ -196,11 +196,11 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
 			ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.fork_before_edit")
 		}
 
-	case base.IsPDFFile(buf):
+	case tool.IsPDFFile(buf):
 		ctx.Data["IsPDFFile"] = true
-	case base.IsVideoFile(buf):
+	case tool.IsVideoFile(buf):
 		ctx.Data["IsVideoFile"] = true
-	case base.IsImageFile(buf):
+	case tool.IsImageFile(buf):
 		ctx.Data["IsImageFile"] = true
 	}
 
@@ -304,7 +304,7 @@ func Home(ctx *context.Context) {
 	ctx.HTML(200, HOME)
 }
 
-func RenderUserCards(ctx *context.Context, total int, getter func(page int) ([]*models.User, error), tpl base.TplName) {
+func RenderUserCards(ctx *context.Context, total int, getter func(page int) ([]*models.User, error), tpl tool.TplName) {
 	page := ctx.QueryInt("page")
 	if page <= 0 {
 		page = 1

+ 5 - 5
routers/repo/webhook.go

@@ -16,16 +16,16 @@ import (
 
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/models/errors"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/form"
 	"github.com/gogits/gogs/pkg/setting"
 )
 
 const (
-	WEBHOOKS        base.TplName = "repo/settings/webhook/base"
-	WEBHOOK_NEW     base.TplName = "repo/settings/webhook/new"
-	ORG_WEBHOOK_NEW base.TplName = "org/settings/webhook_new"
+	WEBHOOKS        tool.TplName = "repo/settings/webhook/base"
+	WEBHOOK_NEW     tool.TplName = "repo/settings/webhook/new"
+	ORG_WEBHOOK_NEW tool.TplName = "org/settings/webhook_new"
 )
 
 func Webhooks(ctx *context.Context) {
@@ -49,7 +49,7 @@ type OrgRepoCtx struct {
 	OrgID       int64
 	RepoID      int64
 	Link        string
-	NewTemplate base.TplName
+	NewTemplate tool.TplName
 }
 
 // getOrgRepoCtx determines whether this is a repo context or organization context.

+ 5 - 5
routers/repo/wiki.go

@@ -12,17 +12,17 @@ import (
 	"github.com/gogits/git-module"
 
 	"github.com/gogits/gogs/models"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/form"
 	"github.com/gogits/gogs/pkg/markup"
 )
 
 const (
-	WIKI_START base.TplName = "repo/wiki/start"
-	WIKI_VIEW  base.TplName = "repo/wiki/view"
-	WIKI_NEW   base.TplName = "repo/wiki/new"
-	WIKI_PAGES base.TplName = "repo/wiki/pages"
+	WIKI_START tool.TplName = "repo/wiki/start"
+	WIKI_VIEW  tool.TplName = "repo/wiki/view"
+	WIKI_NEW   tool.TplName = "repo/wiki/new"
+	WIKI_PAGES tool.TplName = "repo/wiki/pages"
 )
 
 func MustEnableWiki(ctx *context.Context) {

+ 6 - 6
routers/user/auth.go

@@ -13,7 +13,7 @@ import (
 
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/models/errors"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/form"
 	"github.com/gogits/gogs/pkg/mailer"
@@ -21,11 +21,11 @@ import (
 )
 
 const (
-	SIGNIN          base.TplName = "user/auth/signin"
-	SIGNUP          base.TplName = "user/auth/signup"
-	ACTIVATE        base.TplName = "user/auth/activate"
-	FORGOT_PASSWORD base.TplName = "user/auth/forgot_passwd"
-	RESET_PASSWORD  base.TplName = "user/auth/reset_passwd"
+	SIGNIN          tool.TplName = "user/auth/signin"
+	SIGNUP          tool.TplName = "user/auth/signup"
+	ACTIVATE        tool.TplName = "user/auth/activate"
+	FORGOT_PASSWORD tool.TplName = "user/auth/forgot_passwd"
+	RESET_PASSWORD  tool.TplName = "user/auth/reset_passwd"
 )
 
 // AutoSignIn reads cookie and try to auto-login.

+ 6 - 6
routers/user/home.go

@@ -13,17 +13,17 @@ import (
 
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/models/errors"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/setting"
 )
 
 const (
-	DASHBOARD base.TplName = "user/dashboard/dashboard"
-	NEWS_FEED base.TplName = "user/dashboard/feeds"
-	ISSUES    base.TplName = "user/dashboard/issues"
-	PROFILE   base.TplName = "user/profile"
-	ORG_HOME  base.TplName = "org/home"
+	DASHBOARD tool.TplName = "user/dashboard/dashboard"
+	NEWS_FEED tool.TplName = "user/dashboard/feeds"
+	ISSUES    tool.TplName = "user/dashboard/issues"
+	PROFILE   tool.TplName = "user/profile"
+	ORG_HOME  tool.TplName = "org/home"
 )
 
 // getDashboardContextUser finds out dashboard is viewing as which context user.

+ 3 - 3
routers/user/profile.go

@@ -13,15 +13,15 @@ import (
 
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/models/errors"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/setting"
 	"github.com/gogits/gogs/routers/repo"
 )
 
 const (
-	FOLLOWERS base.TplName = "user/meta/followers"
-	STARS     base.TplName = "user/meta/stars"
+	FOLLOWERS tool.TplName = "user/meta/followers"
+	STARS     tool.TplName = "user/meta/stars"
 )
 
 func GetUserByName(ctx *context.Context, name string) *models.User {

+ 14 - 15
routers/user/setting.go

@@ -14,7 +14,7 @@ import (
 
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/models/errors"
-	"github.com/gogits/gogs/pkg/base"
+	"github.com/gogits/gogs/pkg/tool"
 	"github.com/gogits/gogs/pkg/context"
 	"github.com/gogits/gogs/pkg/form"
 	"github.com/gogits/gogs/pkg/mailer"
@@ -22,18 +22,17 @@ import (
 )
 
 const (
-	SETTINGS_PROFILE       base.TplName = "user/settings/profile"
-	SETTINGS_AVATAR        base.TplName = "user/settings/avatar"
-	SETTINGS_PASSWORD      base.TplName = "user/settings/password"
-	SETTINGS_EMAILS        base.TplName = "user/settings/email"
-	SETTINGS_SSH_KEYS      base.TplName = "user/settings/sshkeys"
-	SETTINGS_SOCIAL        base.TplName = "user/settings/social"
-	SETTINGS_APPLICATIONS  base.TplName = "user/settings/applications"
-	SETTINGS_ORGANIZATIONS base.TplName = "user/settings/organizations"
-	SETTINGS_REPOSITORIES  base.TplName = "user/settings/repositories"
-	SETTINGS_DELETE        base.TplName = "user/settings/delete"
-	NOTIFICATION           base.TplName = "user/notification"
-	SECURITY               base.TplName = "user/security"
+	SETTINGS_PROFILE       tool.TplName = "user/settings/profile"
+	SETTINGS_AVATAR        tool.TplName = "user/settings/avatar"
+	SETTINGS_PASSWORD      tool.TplName = "user/settings/password"
+	SETTINGS_EMAILS        tool.TplName = "user/settings/email"
+	SETTINGS_SSH_KEYS      tool.TplName = "user/settings/sshkeys"
+	SETTINGS_SECURITY      tool.TplName = "user/settings/security"
+	SETTINGS_REPOSITORIES  tool.TplName = "user/settings/repositories"
+	SETTINGS_ORGANIZATIONS tool.TplName = "user/settings/organizations"
+	SETTINGS_APPLICATIONS  tool.TplName = "user/settings/applications"
+	SETTINGS_DELETE        tool.TplName = "user/settings/delete"
+	NOTIFICATION           tool.TplName = "user/notification"
 )
 
 func Settings(c *context.Context) {
@@ -116,7 +115,7 @@ func SettingsPost(ctx *context.Context, f form.UpdateProfile) {
 func UpdateAvatarSetting(ctx *context.Context, f form.Avatar, ctxUser *models.User) error {
 	ctxUser.UseCustomAvatar = f.Source == form.AVATAR_LOCAL
 	if len(f.Gravatar) > 0 {
-		ctxUser.Avatar = base.EncodeMD5(f.Gravatar)
+		ctxUser.Avatar = tool.EncodeMD5(f.Gravatar)
 		ctxUser.AvatarEmail = f.Gravatar
 	}
 
@@ -131,7 +130,7 @@ func UpdateAvatarSetting(ctx *context.Context, f form.Avatar, ctxUser *models.Us
 		if err != nil {
 			return fmt.Errorf("ioutil.ReadAll: %v", err)
 		}
-		if !base.IsImageFile(data) {
+		if !tool.IsImageFile(data) {
 			return errors.New(ctx.Tr("settings.uploaded_avatar_not_a_image"))
 		}
 		if err = ctxUser.UploadAvatar(data); err != nil {

+ 4 - 4
templates/user/settings/navbar.tmpl

@@ -16,14 +16,14 @@
 		<a class="{{if .PageIsSettingsSSHKeys}}active{{end}} item" href="{{AppSubUrl}}/user/settings/ssh">
 			{{.i18n.Tr "settings.ssh_keys"}}
 		</a>
-		<a class="{{if .PageIsSettingsApplications}}active{{end}} item" href="{{AppSubUrl}}/user/settings/applications">
-			{{.i18n.Tr "settings.applications"}}
+		<a class="{{if .PageIsSettingsRepositories}}active{{end}} item" href="{{AppSubUrl}}/user/settings/repositories">
+			{{.i18n.Tr "settings.repos"}}
 		</a>
 		<a class="{{if .PageIsSettingsOrganizations}}active{{end}} item" href="{{AppSubUrl}}/user/settings/organizations">
 			{{.i18n.Tr "settings.orgs"}}
 		</a>
-		<a class="{{if .PageIsSettingsRepositories}}active{{end}} item" href="{{AppSubUrl}}/user/settings/repositories">
-			{{.i18n.Tr "settings.repos"}}
+		<a class="{{if .PageIsSettingsApplications}}active{{end}} item" href="{{AppSubUrl}}/user/settings/applications">
+			{{.i18n.Tr "settings.applications"}}
 		</a>
 		<a class="{{if .PageIsSettingsDelete}}active{{end}} item" href="{{AppSubUrl}}/user/settings/delete">
 			{{.i18n.Tr "settings.delete"}}